C++ - Deriving Classes - Error: expected primary expression before'int' - c++

First post so be gentle with me...
I am trying to implement a derived class and am having problems and no matter what i try am getting compilation errors. I am sure it is something simple i have missed but am very new to this and all my research has given me no help (or i have just missed it cause i dont know what I am doing!).
This is my header file:
#ifndef WEEKDAY_H
#define WEEKDAY_H
#include <iostream>
#include <string>
#include <ctime>
using namespace std;
class DateTime{
public:
DateTime(int y, int m, int d, int h = 0, int min = 0, int s = 0);
void display();
protected:
string get_string_component(char option, tm* dateStruct);
int get_year_days(tm* dateStruct);
struct tm DTstruct;
private:
bool validate_data( int y, int m, int d, int h, int min, int s);
};
class WeekDay : public DateTime{
public:
WeekDay(int y, int m, int d, int h = 0, int min = 0, int s = 0);
void display();
};
#endif
This is an excerpt from the .cpp file that i am trying to implement:
WeekDay::WeekDay(int y, int m, int d, int h, int min, int s)
: DateTime(int y, int m, int d, int h, int min, int s),{
}
void WeekDay::display(){
}
At present I am getting the following error:
weekday.cpp: In constructor 'WeekDay::WeekDay(int, int, int, int, int, int)':
weekday.cpp:58:13: error: expected primary-expression before 'int'
weekday.cpp:58:20: error: expected primary-expression before 'int'
weekday.cpp:58:27: error: expected primary-expression before 'int'
weekday.cpp:58:34: error: expected primary-expression before 'int'
weekday.cpp:58:41: error: expected primary-expression before 'int'
weekday.cpp:58:50: error: expected primary-expression before 'int'
weekday.cpp:60:1: error: expected identifier before '{' token
If i change things around in the .cpp file i get different errors - obviously.
Basically i really don't know how to do this and have struggled trying to find the correct way...
Anyway if someone can point me in the right direction it would be greatly appreciated...
Thanks

You're using the member initialization list incorrectly. If you want to pass the values of the arguments passed to the WeekDay constructor to the constructor of DateTime, you need to remove the types:
WeekDay::WeekDay(int y, int m, int d, int h, int min, int s)
: DateTime(y, m, d, h, min, s) {
}
Consider it like calling a function (because actually, that's what it's doing). If you have a function like void foo(int x);, you don't call it by writing foo(int 5), do you?

: DateTime(int y, int m, int d, int h, int min, int s),{
remove all the "int"s from that line.

this line:
: DateTime(int y, int m, int d, int h, int min, int s),{
should be:
: DateTime(y, m, d,h, min,s) {

The offending line is this one:
: DateTime(int y, int m, int d, int h, int min, int s),{
First you have a trailing comma before the ,, then you should remove the int you put in this line: you are not defining the superclass constructor, but calling it. Think of this as an ordinary (unbound) function: you call functions with f(x), not f(int x).

The member-initializer list takes a comma separated list of data members and initializes it with the parameter you supply. int x is not a value, it's actually a syntax error in this case. However, x would be a value.
WeekDay::WeekDay(int y, int m, int d, int h, int min, int s)
: DateTime(y, m, d, h, min, s)

Related

Ambiguity error using overload in c++

I have tried to use overload with floating and integer. When I only used the integer, the code worked fine, but when I included the floating it gave me errors. The code is the following:
#include <iostream>
using namespace std;
int calculate(int x,int y);
float calculate(float x,float y);
const int MAININT=4;
int main()
{
int result=calculate(5,5);
float fresult=calculate(7.5,7.5); LINE X
cout << (result + MAININT + fresult); LINE Y
return 0;
}
int calculate(int x,int y)
{
int result=x*y;
return result;
}
float calculate(float x,float y)
{
int result=x*y;
return result;
}
By deleting LINE X and fresult from LINE Y, the code give me no errors. So I assume there must be something wrong in LINE X, but I don't understand why I get errors.
The error messages I got was :
[Error] call of overloaded 'calculate(double, double)' is ambiguous
[Note] candidates are:
[Note] int calculate(int, int)
[Note] float calculate(float, float)
I did not understand the error messages, so I didn't include them. I understand what I did wrong from the answer of songyuanyao, but next time I will include the error messages in my question from the start so it will be easier to see what I have done wrong in the code.
Because 7.5 is a double (see floating point literal), not a float; and implicit conversion to int or float are considered as the same ranking.
If your suppose 7.5 as float here you could use the suffix f or F to make it a float literal. e.g.
float fresult = calculate(7.5f, 7.5f); // 7.5f is a float literal; no ambiguity
Or use explicit conversion:
float fresult = calculate(static_cast<float>(7.5), static_cast<float>(7.5));
You should have posted the error message which is self-explanatory in itself. The error message mentions about the candidate functions and how they are not exactly compatible:
error: call of overloaded 'calculate(double, double)' is ambiguous
float fresult=calculate(7.5,7.5);
^
note: candidate: int calculate(int, int)
int calculate(int x,int y);
^
note: candidate: float calculate(float, float)
float calculate(float x,float y);
By default, a floating-point literal (7.5 in your case) is of type double.
Here is the list of suffix that determines the type of the floating-point literal:
(no suffix) defines double
f F defines float
l L defines long double
While others have already told you where the ambiguity error comes from, I'm surprised nobody has mentioned the easiest solution to the problem: Just use double instead of float.
Just like int should be your default choice for integer numbers, double should be your default choice for floating-point numbers. float is for very special use cases, none of which are likely to apply in your situation. See "When do you use float and when do you use double" over at Software Engineering Stack Exchange.
As a side effect of following this guideline, your particular problem here disappears:
#include <iostream>
using namespace std;
int calculate(int x,int y);
double calculate(double x, double y);
const int MAININT=4;
int main()
{
int result=calculate(5,5);
double fresult=calculate(7.5,7.5);
cout << (result + MAININT + fresult);
return 0;
}
int calculate(int x,int y)
{
int result=x*y;
return result;
}
double calculate(double x, double y)
{
double result=x*y; // the `int` here was a mistake in your original code anyway
return result;
}
Some further suggestions:
Avoid using namespace std;.
Reserve ALL_CAPS for preprocessor macros.

Default Argument in non-inline Constructor

I've written a Cell class. When I write constructor with default parameters as inline function, there is no problem
cell.h
Class Cell{
public:
Cell(int x, int y, char sign='.'):X(x), Y(y), Sign(sign){}
};
But if I want to move that implementation in my source file like this:
cell.h
Class Cell{
public:
Cell(int x, int y, char sign='.');
};
cell.cpp
Cell::Cell(int x, int y, char sign='.'):X(x), Y(y), Sign(sign){}
Compiler says:
Reversi.cpp:1144:43: error: default argument given for parameter 3 of ‘Cell::Cell(int, int, char)’ [-fpermissive]
Cell::Cell(int x, int y, char sign='.'):X(x), Y(y), Sign(sign){}
^
In file included from Reversi.cpp:7:0:
Reversi.h:16:5: note: previous specification in ‘Cell::Cell(int, int, char)’ here
Cell(int x, int y, char sign='.');
^
You're trying to specify the default parameters in both files. Only do it within the Header File, and the compiler will stop complaining.
cell.h
Class Cell
{
public:
Cell(int x, int y, char sign);
};
cell.cpp
Cell::Cell(int x, int y, char sign='.'):X(x), Y(y), Sign(sign)
{
}
Specify the default argument only in the member function declaration within the class definition in the header. Otherwise all other modules that include the header will know nothing about the default argument.
You may not declare a default argument for the same parameter more than one time in the same declarative region and the compiler says about this.
You can't create two implementations or provide two versions of default parameters.
You should provide default parameters in the header file and provide either inline implementation in the header file or in the correspondent cpp file.
cell.h
#pragma once
class Cell {
public:
Cell(int x, int y, char sign = '.');
int X;
int Y;
char Sign;
};
cell.cpp
#include "cell.h"
Cell::Cell(int x, int y, char sign): X(x), Y(y), Sign(sign) {}

C++ Not letting me use other constructor in initialization list

I'm trying to have a constructor call other constructors in their initialization list for I don't have duplicate logic. Here is what my .h file looks like:
class Button : public Component
{
public:
Button(int x, int y, int width, int height, string normalSrc, string hoverSrc, string downSrc);
Button(int x, int y, int width, int height, string normalSrc, string hoverSrc, string downSrc, Uint8 r, Uint8 g, Uint8 b);
Button(int x, int y, int width, int height, string src) : Button(x, y, width, height, src, src, src) { }
Button(int x, int y, int width, int height, string src, Uint8 r, Uint8 g, Uint8 b) : Button(x, y, width, height, src, src, src, r, g, b) { }
~Button();
but when I try to compile (using -std=c++0x as an extra compiler flag) I get this error:
In file included from /home/villages/Desktop/ogam-january-pipes/src/Vesper/Ui/Button.cpp:8:0:
/home/villages/Desktop/ogam-january-pipes/src/Vesper/Ui/Button.h: In constructor ‘Button::Button(int, int, int, int, std::string)’:
/home/villages/Desktop/ogam-january-pipes/src/Vesper/Ui/Button.h:29:60: error: type ‘Button’ is not a direct base of ‘Button’
/home/villages/Desktop/ogam-january-pipes/src/Vesper/Ui/Button.h: In constructor ‘Button::Button(int, int, int, int, std::string, Uint8, Uint8, Uint8)’:
/home/villages/Desktop/ogam-january-pipes/src/Vesper/Ui/Button.h:30:87: error: type ‘Button’ is not a direct base of ‘Button’
make[2]: *** [CMakeFiles/Villages.dir/src/Vesper/Ui/Button.cpp.o] Error 1
make[1]: *** [CMakeFiles/Villages.dir/all] Error 2
make: *** [all] Error 2
What am I doing wrong?
Thanks!
What am I doing wrong?
You are using the wrong compiler/version. The delegating constructors feature is a C++11 feature, and not all compilers have caught up yet.
According to this table GCC supports it since 4.7, Clang since 3.0, and MSVC since Nov 2012 CTP.

How do I pass a C++ callback to a C library function?

I'm developing my code using C++ and want to use MPFIT nonlinear curve fitting library, which is developed in C but allows to compile in C++.
For example I have a class named "myClass", and this class has a function myClass::Execute()
I include "mpfit.h" to myClass.h file. And try to call a function called mpfit from Execute().
int status = mpfit(ErrorFunction, num1, num2, xsub_1D, 0, 0, (void *) &variables, &result);
The problem is ErrorFunction is a function of myClass. So compiler gives error when I try to use this. I tried to carry the ErrorFunction out of the class object, but this time I take the error given below:
Error when the ErrorFunction is outside of the class:
Error 4 error C2664: 'mpfit' : cannot convert parameter 1 from 'int
(__cdecl *)(int,int,double *,double,double *,void *)' to
'mp_func'
Error when the ErrorFunction is inside the class:
Error 3 error C3867: 'myClass::ErrorFunction': function call missing argument list; use '&myClass::ErrorFunction' to
Definition of error function:
int ErrorFunction(int dummy1, int dummy2, double* xsub, double *diff, double **dvec, void *vars)
How can I call this function and parse it into mpfit, which is a C function?
mp_func is defined as:
/* Enforce type of fitting function */
typedef int (*mp_func)(int m, /* Number of functions (elts of fvec) */
int n, /* Number of variables (elts of x) */
double *x, /* I - Parameters */
double *fvec, /* O - function values */
double **dvec, /* O - function derivatives (optional)*/
void *private_data); /* I/O - function private data*/
Make sure that your calling conventions match. C libraries use the C calling convention, or cdecl (__cdecl). If you're using the mp_func typedef within C++, it could be defaulting to the compiler's standard calling convention, or stdcall (__stdcall). Either make a new typedef or change it to the following:
typedef int __cdecl (*mp_func)(int m, /* Number of functions (elts of fvec) */
int n, /* Number of variables (elts of x) */
double *x, /* I - Parameters */
double *fvec, /* O - function values */
double **dvec, /* O - function derivatives (optional)*/
void *private_data); /* I/O - function private data*/
And when you declare ErrorFunction, also declare it as __cdecl:
int __cdecl ErrorFunction(int, int, double*, double *, double **, void *);
If the compiler still complains when calling the mpfit function, you can try casting your function pointer to the mp_func typedef with cdecl:
int status = mpfit((mp_func)ErrorFunction, num1, num2, xsub_1D, 0, 0, (void *) &variables, &result);
Given the definitions of mpfit() and mp_func that you have shown, you would need to use the private_data parameter of mp_func to pass your class's this pointer around. You are currently using that parameter to pass your variables item around instead. Make variables be a member of your class (if it is not already) and then pass this to mpfit() instead:
class MyClass
{
private:
TheDataType variables;
static int ErrorFunction(int m, int n, double *x, double *fvec, double **dvec, MyClass *pThis);
public:
void DoIt();
};
void MyClass::DoIt()
{
// ...
int status = mpfit((mp_func)&ErrorFunction, num1, num2, xsub_1D, 0, 0, this, &result);
// ...
}
int MyClass::ErrorFunction(int m, int n, double* x, double *fvec, double **dvec, MyClass *pThis)
{
// use pThis->variables as needed ...
}
Or:
class MyClass
{
private:
static int MPFitErrorFunction(int m, int n, double *x, double *fvec, double **dvec, MyClass *pThis);
int MyErrorFunction(int m, int n, double *x, double *fvec, double **dvec);
public:
void DoIt();
};
void MyClass::DoIt()
{
// ...
int status = mpfit((mp_func)&MPFitErrorFunction, num1, num2, xsub_1D, 0, 0, this, &result);
// ...
}
int MyClass::MPFitErrorFunction(int m, int n, double* x, double *fvec, double **dvec, MyClass *pThis)
{
return pThis->MyErrorFunction(m, n, x, fvec, dvec);
}
int MyClass::MyErrorFunction(int m, int n, double* x, double *fvec, double **dvec)
{
// use this->variables as needed ...
}
Looks like instead of:
int ErrorFunction(int dummy1, int dummy2, double* xsub, double diff, double *dvec, void *vars)
it should be:
int ErrorFunction(int dummy1, int dummy2, double* xsub, double *diff, double **dvec, void *vars)
to match your
typedef int (*mp_func)(int m, /* Number of functions (elts of fvec) */
int n, /* Number of variables (elts of x) */
double *x, /* I - Parameters */
double *fvec, /* O - function values */
double **dvec, /* O - function derivatives (optional)*/
void *private_data); /* I/O - function private data*/
Your callback must be declared extern "C" for this to work.
Edit: I see people are having hard time grasping this fact. The standard says (7.5/1):
Two function types with different language linkages are distinct types
even if they are otherwise identical.
There's a standard idiom for C++ - to - C, using the pimpl idiom:
foo_c.h:
#ifdef __cplusplus
extern "C" {
#endif
//forward declaration. clients of foo_c.h should only hold pointers to Foo_c
typedef struct Foo_c Foo_c;
int someMethod(Foo_c* foo);
#ifdef __cplusplus
}
#endif
foo_c.cpp:
#include <foo.h>
struct Foo_c {
Foo foo;
}
int someMethod(Foo_c* foo) {
try {
foo->foo.someMethod();
return 0; //no error
}
catch(...) {
return 1; //error
}
}
(Edited for extern "C"'s per below answer.)

C++ redifinition of'..' and previously declared here errors

I have already searched for this type of error and found a few threads, but each one recommended using #ifndef to make sure the header file is only loaded once. I have done this and still get an error. The odd thing is this error:
circle.cc:25:6: error: prototype for ‘void circle::populate_classobj(int, int, int)’ does not match any in class ‘circle’
says my function only has 3 int's but every place i have that function, i have 4 ints.
here is my class header file
#ifndef _CIRCLE_H_
#define _CIRCLE_H_
#define PI 3.14159
class circle
{
public:
float radius(int x1, int x2, int y1, int y2);
float circumference(float d);
float area(float d);
void populate_classobj(int, int, int, int);
protected:
float distance(int x1, int x2, int y1, int y2);
private:
int x1, y1, x2, y2;
};
#endif // _CIRCLE_H_
Here is my function call in my class file circle.cc
void circle::populate_classobj(int cx1, int cx2, int cy1, int cy1)
{
x1=cx1;
x2=cx2;
y1=cy1;
y2=cy2;
}
and here is what i actually call in main
mycircle.populate_classobj(x1,x2,y1,y2);
there are variables called x1, x2, y1, y2 in main
The really odd thing is that the redefinition error is only for cy1, not cx1, cx2 or cy2
Thanks for any help and if you need to see more of my code, ask for it.
-Will
Last two parameters are exactly same as shown below. Hence the redefinition error.
void circle::populate_classobj(int cx1, int cx2, int cy1, int cy1)
^^^ ^^^
I think you wanted to write:
void circle::populate_classobj(int cx1, int cx2, int cy1, int cy2)
void circle::populate_classobj(int cx1, int cx2, int cy1, int cy1)
You see there the redefinition of cy1, since both last arguments are called the same. By the way, names beginning with an underscore in the global namespace are reserved for the implementation, you should drop the leading underscore from your scope guards.
void circle::populate_classobj(int cx1, int cx2, int cy1, int cy1)
// ^^^ ^^^
Is this a question typo, or do you really have two parameters in the function definition named cy1?
Your definition of populate_classobj uses the same name cy1 for two different parameters.