Object construction / forward function declaration ambiguity

Observation: the codes pasted below were tested only with GCC 4.4.1, and I'm only interested in them working with GCC.

Hello,

More than once several times I came across an expression about the construction of an object that I did not understand, and only today I noticed what ambiguity is introduced by it. I will explain how to reproduce it and would like to know if there is a way to fix it (C ++ 0x is allowed). Here it is.

Suppose there is a class whose constructor takes only one argument, and this one type of argument is another class with a default constructor. For example:.

 struct ArgType {}; class Class { public: Class(ArgType arg); }; 

If I try to build an object of type Class on the stack, I get ambiguity:

 Class c(ArgType()); // is this an object construction or a forward declaration // of a function "c" returning `Class` and taking a pointer // to a function returning `ArgType` and taking no arguments // as argument? (oh yeh, loli haets awkward syntax in teh // saucecode) 

I call this the construction of an object, but the compiler insists that it is a declaration inside the function body. For you who still do not understand this, here is a complete working example:

 #include <iostream> struct ArgType {}; struct Class {}; ArgType func() { std::cout << "func()\n"; return ArgType(); } int main() { Class c(ArgType()); c(func); // prints "func()\n" } Class c(ArgType funcPtr()) // Class c(ArgType (*funcPtr)()) also works { funcPtr(); return Class(); } 

So, enough examples. Can anyone help me get around this without doing anything too anti-idiomatic (I'm a library developer and people love idiomatic libraries)?

- edit

Nothing. This is a hoax. The most unpleasant parsing: why A a (()); work? .

Thank you sbi.

+7
c ++ object-construction forward-declaration ambiguity
source share
3 answers

This is called the "C ++ most vexing parse". See here , here and here .

+5
source share

Based on the allowed "C ++ 0x", the correct answer is (possibly) to change the definition:

 Class c(ArgType {}); 

Simple, understandable and fully loads the library user, not the author!

Edit: Yes, ctor is called - C ++ 0x adds List-Initialization as a unique way to delimit initializer lists. It cannot be parsed incorrectly, as in your example, but otherwise the meaning is about the same as if you used parentheses. See N3000 , third paragraph in accordance with ยง8.5.4 / 3. You can write ctor to get the list of initializers as a single argument, or the elements in the list of initializers can be matched with the ctor arguments separately.

+1
source share

Simplify a bit.

 int f1(); 

What is it? The compiler (and I) declares this a front declaration for the function returning an integer.

How about this?

 int f2(double ); 

The compiler (and I) says this front declaration for a function that takes a double argument and returns an int.

So you tried this:

 ClassType c = ClassType(ArgType()); 

Take a look at C ++ faq lite on constructors for explanations and examples.

+1
source share

All Articles