0

Possible Duplicate:
Why is it an error to use an empty set of brackets to call a constructor with no arguments?
Most vexing parse: why doesn't A a(()); work?

This one gets me mad. Maybe its just too simple.

struct Foo
{
  Foo() {}
  Foo(const Foo& f) {}
  void work() {}
};

int main()
{
  Foo f( Foo() );
  f.work();
}

GCC 4.6 gives me:

error: request for member ‘work’ in ‘f’, which is of non-class type ‘Foo(Foo (*)())’

After elision of the copy operation the effective code might look like:

int main()
{
  Foo f;
  f.work();
}

But why can't i call work() ??

Edit:

Yes, duplicate (see below). Didn't find the original post when search first because the source of the symptoms of this is located where i didn't expect that.

Community
  • 1
  • 1
ritter
  • 7,447
  • 7
  • 51
  • 84
  • 1
    Why do you write `Foo f( Foo() );` in the first place, what is wrong with writing `Foo f;`, which should work as expected. Your first version creates a completely different type, as you can see in the error message. – Nobody moving away from SE Jul 26 '12 at 11:12
  • Its of course a bit academic. Comes from a study what constructors are called – ritter Jul 26 '12 at 11:13

4 Answers4

3

Because Foo f( Foo() ); is a function declaration.

I think you want: Foo f;

Or in case you want to copy-construct:

Foo f( (Foo()) );
Andrew
  • 24,218
  • 13
  • 61
  • 90
1

f is effectively a function declaration within main function. Try

Foo f((Foo())); // to make the definition of f explicit enough.
nurettin
  • 11,090
  • 5
  • 65
  • 85
1

n3337 8.2

The ambiguity arising from the similarity between a function-style cast and a declaration mentioned in 6.8 can also occur in the context of a declaration. In that context, the choice is between a function declaration with a redundant set of parentheses around a parameter name and an object declaration with a function-style cast as the initializer. Just as for the ambiguities mentioned in 6.8, the resolution is to consider any construct that could possibly be a declaration a declaration. [ Note: A declaration can be explicitly disambiguated by a nonfunction-style cast, by an = to indicate initialization or by removing the redundant parentheses around the parameter name. — end note ] [ Example:

struct S {
S(int);
};
void foo(double a) {
S w(int(a));
//function declaration
S x(int());
//function declaration
S y((int)a);
//object declaration
S z = int(a);
//object declaration
}

— end example ]

ForEveR
  • 55,233
  • 2
  • 119
  • 133
1

C++ parser interprets Foo f(Foo()); expression as the function declaration with the signature Foo(Foo(*)()), i.e. a function returning Foo and taking a function pointer to the function returning Foo. Adding explicit parenthesis around the argument like so Foo f((Foo())); will resolve the ambiguity. But consider actually just doing Foo f; which avoids redundant code.

yuri kilochek
  • 12,709
  • 2
  • 32
  • 59
  • A function declaration is not allowed within a basic block. How can it be interpreted as such? – ritter Jul 26 '12 at 11:19
  • @Frank That is a C legacy [link](http://stackoverflow.com/questions/6089452/is-there-a-use-for-function-declarations-inside-functions) – yuri kilochek Jul 26 '12 at 11:23