#include<iostream>
class name
{
public:
int a;
name():a(0){};
};
void add(name * pname)
{
pname = NULL;
}
int main()
{
name varName();
name * pName = new name();
add(pName);
add(&varName);//error C2664: 'add' : cannot convert parameter 1 from 'name __cdecl *)(void)' to 'name *'
}
views:
421answers:
4The error is on the first line of the main function:
name varName();
You are not creating an instance of class name with the default constructor, you are actually declaring a new function called varName, with no parameters, which returns a name instance.
You should instead write:
name varName;
name varName();
is interpreted as a local function declaration. To invoke the default constructor, use
name varName;
instead. Most vexing, yes.
I think it's worth telling you about a similar problem, that also causes trouble:
struct foo { };
struct bar { bar(foo f); };
int main() {
// does *not* create a bar object initialized by a default constructed
// foo object.
bar b(foo());
}
What b really is is a function that returns a bar
and takes as first argument a pointer to a function that returns a foo taking no arguments. It's the same as:
bar b(foo(*)());
If you want to create a bar object initialized by a default constructed foo, put parentheses around the argument. That makes it doesn't look like a function declaration anymore, and the compiler will interpret it like you want:
bar b((foo()));
There are also non-obvious cases where a compiler error should be risen. GCC gets this wrong, but Comeau gets it right again. Consider the following snippet
struct foo {
static bool const value = false;
};
int main() {
int v(int(foo::value));
}
You will probably expect that this takes the static constant, and casts it to int
, initializing the v
variable to 0
? No, it won't according to the Standard, because the initializer can be interpreted as a declaration, according to pure syntax analysis, as the following shows
struct foo {
static int value;
};
// valid, parentheses are redundant! Defines `foo::value`.
int (foo::value);
Whenever the initializer can be interpreted as a declaration, in such a situation whole the declaration will declare a function. So, the line in main
declares a function like the following, omitting the redundant and meaningless parentheses
int v(int foo::value);
And this will cause a compiler error when parsing the function declaration, because a function parameter name may not be qualified.
It's also worth noting that your add() function doesn't have any lasting effects -- all it's doing is assigning a value to pname, which is a copy of the pointer you pass into it. If you want to actually have that assignment stick, you would need to pass the pointer by reference as "name*& pname".