This question already has answers here:
A confusing detail about the Most Vexing Parse
(4 answers)
Closed 3 years ago.
Taken directly from http://herbsutter.com/2013/05/09/gotw-1-solution/
While widget w(); is clear for me, I have no idea how can the below code be a function declaration?
// same problem (gadget and doodad are types)
//
widget w( gadget(), doodad() ); // pitfall: not a variable declaration
How is this possible?
In a function declaration, arguments of type array decay into pointers to the first element, arguments of type function decay into a function pointer, so the signature would be:
widget w( gadget(*)(), doodad(*)() );
That is, a function that takes as the first argument a pointer to a function taking no arguments and returning gadget, that takes as second argument a pointer to a function taking no arguments and returning a doodad and that the function itself returns a widget
There are even more interesting or confusing cases, like:
// assume 'x' is a variable defined somewhere:
widget w(gadget(x));
How could that be interpreted as a function declaration? I mean, x is a variable, right? Well, when declaring a variable you can add extra parenthesis, so gadget x; and gadget (x); both declare the same variable x. The same applies to function arguments so the code above looks like a declaration of a function that takes a first argument named x of type gadget and returns a widget...
It's function that gets two functions, that returns gadget and doodad and either of them gets no arguments.
Example that compiles fine.
#include <iostream>
class widget{};
class gadget{};
class doodad{};
gadget a(){}
doodad b() {};
widget w( gadget(), doodad() ){
}
int main() {
w(a,b);
return 0;
}
http://ideone.com/YjZK9Y
Related
This question already has answers here:
Default constructor with empty brackets
(9 answers)
Closed 3 years ago.
The other day i was trying to create an object by calling the default constructor of another class, and it ended up making a function declaration, Here is an example:
struct integer {
integer(){} //Default constructor.
};
struct rational {
rational(integer n, integer d){} //Default constructor.
};
void multiply(rational(), rational()) { //Valid syntax? Takes two function pointers.
}
rational one_half() {
return rational(integer(), integer()); //Here doesnt make a function declaration.
}
int main() {
rational num(integer(), integer()); //Here makes a function declaration,
//instead of constructing a rational object.
multiply(one_half, one_half); //function taking two function pointers.
}
Why does this happen? I know and can call the constructor like this integer::integer() but i would like to understand what's happening here and why integer() is behaving like integer(*)() in this example.
Why does this happen?
The rule comes from C, in C++ it works the same. From c++ standard dcl.fct inside a function parameter list:
... After determining the type of each parameter, any parameter of type “array of T” or of function type T is adjusted to be “pointer to T”. ...
Inside a function parameter list a parameter that has a type of function type integer() is converted to a pointer to that type integer(*)().
So is integer() in fact equal to integer(*)()?
Inside function parameter list, yes.
This question already has answers here:
A confusing detail about the Most Vexing Parse
(4 answers)
Closed 3 years ago.
Taken directly from http://herbsutter.com/2013/05/09/gotw-1-solution/
While widget w(); is clear for me, I have no idea how can the below code be a function declaration?
// same problem (gadget and doodad are types)
//
widget w( gadget(), doodad() ); // pitfall: not a variable declaration
How is this possible?
In a function declaration, arguments of type array decay into pointers to the first element, arguments of type function decay into a function pointer, so the signature would be:
widget w( gadget(*)(), doodad(*)() );
That is, a function that takes as the first argument a pointer to a function taking no arguments and returning gadget, that takes as second argument a pointer to a function taking no arguments and returning a doodad and that the function itself returns a widget
There are even more interesting or confusing cases, like:
// assume 'x' is a variable defined somewhere:
widget w(gadget(x));
How could that be interpreted as a function declaration? I mean, x is a variable, right? Well, when declaring a variable you can add extra parenthesis, so gadget x; and gadget (x); both declare the same variable x. The same applies to function arguments so the code above looks like a declaration of a function that takes a first argument named x of type gadget and returns a widget...
It's function that gets two functions, that returns gadget and doodad and either of them gets no arguments.
Example that compiles fine.
#include <iostream>
class widget{};
class gadget{};
class doodad{};
gadget a(){}
doodad b() {};
widget w( gadget(), doodad() ){
}
int main() {
w(a,b);
return 0;
}
http://ideone.com/YjZK9Y
This question already has answers here:
My attempt at value initialization is interpreted as a function declaration, and why doesn't A a(()); solve it?
(5 answers)
Closed 6 years ago.
First a disclaimer. I've been reading the multitude of questions on this topic, yet I can't get mine to work for me. Mostly I was basing my attempt off of this link, which seems to imply that as long as the function definition has & in it, then I can just pass the object into the function by name. However I keep getting the following errors:
assembler.cpp: In function ‘int main()’:
assembler.cpp:56:21: error: invalid initialization of non-const reference of type ‘Symbol_Table&’ from an rvalue of type ‘Symbol_Table (*)()’
get_input(Table_obj);
assembler.cpp:30:6: error: in passing argument 1 of ‘void get_input(Symbol_Table&)’
void get_input(Symbol_Table& Table_ptr)
As for my actual code, the relevant bits are below. The get_input function is just reading from a file and creating an object of a different type to work with. Through the course of the program running, the Symbol_Table object will have it's members changed so I need to pass it by reference without it being const, which was the only "solution" I could find.
void get_input(Symbol_Table& Table_ptr)
{
do_stuff();
}
int main()
{
Symbol_Table Table_obj();
get_input(Table_obj);
}
I don't think the class definition of Symbol_Table is needed, but I can edit it in if needed.
Symbol_Table Table_obj();
That doesn't create a variable called Table_obj of type Symbol_Table, that's a declaration for a function called Table_obj which takes no arguments and returns a Symbol_Table.
Do one of these:
Symbol_Table Table_obj;
Symbol_Table Table_obj{}; //C++11
You are declaring a function named Table_obj which will return Symbol_Table. This is not what you intend.
int main()
{
Symbol_Table Table_obj; // Construct an object
get_input(Table_obj);
}
This is like:
int get(); // Function
But you want:
int get; // Variable
Confusion reason:
int get(0); // int constructor takes one argument
The problem is that
Symbol_Table Table_obj();
does not make a Symbol_Table object named Table_obj but instead makes a function named Table_obj that takes nothing and returns a Symbol_Table. Change it to
Symbol_Table Table_obj;
and it will compile just fine.
This question already has answers here:
My attempt at value initialization is interpreted as a function declaration, and why doesn't A a(()); solve it?
(5 answers)
Closed 8 years ago.
I met this C++ question:
Question: Is the following a definition or a declaration?
Foo f(Bar());
Answer: It is possibly either a declaration of a function that takes type Bar and returns type Foo or it is a definition of f as a type Foo, which has a constructor that takes type Bar. The problem is the syntax for both is identical so to resolve this problem the C++ standard states that a compiler must prefer function declarations to object definitions where it is unable to make a distinction.
-- I don't understand why it can be "a declaration of a function that takes type Bar and returns type Foo"? how come a parenthesis "()" appear in parameter list?
The function f actually takes a function pointer to a function that takes no arguments and gives a Bar. The type of the argument to f is Bar (*)().
This code fails to compile (and we can see the actual type of the argument in the error message):
class Foo { };
class Bar { };
Foo f(Bar());
int main() {
Bar b;
f(b);
return 0;
}
But this code does compile:
class Foo { };
class Bar { };
Foo f(Bar());
Bar g();
int main() {
f(g);
return 0;
}
The second meaning it could have, as you say in the question, is that you are making a new Foo object called f and you are calling the constructor with Bar() (a new instance of Bar). It would be similar to:
Foo f = Foo(Bar());
In this situation of Foo f(Bar()); though, the first interpretation is chosen by the compiler.
Somewhat confusingly, if you add another set of parentheses, as in
Foo f((Bar()));
the compiler picks the second interpretation.
For example:
struct test
{};
void thing(test())
{}
int main()
{
thing(test());
}
This code would give me error; however, the next example won't give me error:
void thing(int())
{}
int main()
{
thing(int());
}
My main question is, why the first example isn't possible and the second one is? Ultimately, both test and int are types, so I can't think why declaring an anonymous object of test in the thing function argument list isn't possible whereas declaring an anonymous object of type int in the thing function argument list is.
It is possible; it's just that you're doing it wrong.
Here is a declaration of a function taking an unnamed parameter of type test:
void thing(test);
Here is a declaration of a function taking an unnamed parameter of type pointer-to-function-returning-test:
void thing(test());
You want the former, not the latter.
That your second code example works is actually a magical oddity, stemming from the fact that int() is 0 is a valid null pointer constant, which may be used to initialise a function pointer; the example breaks as soon as you swap int() for some other integer, or if you run the code in a completely compliant C++14 compiler (because C++14 made it so that 0 but not int() is a valid null pointer constant).