问题
I am wrestling with the C2751 compiler error and don't quite understand what exactly causes it. The following little code produces the error:
#include <iostream>
class A {
public:
A () { std::cout << "A constructed" << std::endl; };
static A giveA () { return A (); }
};
class B {
public:
B (const A& a) { std::cout << "B constructed" << std::endl; }
};
int main () {
B b1 = B (A::giveA ()); // works
B b2 (B (A::giveA ())); // C2751
B b3 (A::giveA ()); // works
}
Compiler output:
consoleapplication1.cpp(21): error C2751: 'A::giveA': the name of a function parameter cannot be qualified
Why can't I call the constructor explicitly for b2
?
回答1:
It's the problem of the most vexing parse. Compiling under clang gives a full diagnostic:
<source>:18:17: error: parameter declarator cannot be qualified
B b2 (B (A::giveA ())); // C2751
~~~^
<source>:18:10: warning: parentheses were disambiguated as a function declaration [-Wvexing-parse]
B b2 (B (A::giveA ())); // C2751
^~~~~~~~~~~~~~~~~
<source>:18:11: note: add a pair of parentheses to declare a variable
B b2 (B (A::giveA ())); // C2751
^
( )
1 warning and 1 error generated.
Compiler exited with result code 1
Doing as the compiler suggests fixes it:
B b2 ((B (A::giveA ()))); // no error
回答2:
B b2 (B (A::giveA ()));
Even if you had a copy constructor of B
class, you'd still get this error since the line above conforms to the grammar rules of a function-declaration. Having parenthesis around B(A::give())
solves your problem.
回答3:
Ah, the ol' problem of the most vexing parse.
This line here
B b2 (B (A::giveA ())); // C2751
is interpreted as a function b2
returning B
and taking a parameter called A::giveA
of function type B()
. The C2751 error is caused by the invalid name A::giveA
: you cannot use a qualified name as a parameter name.
To copy a temporary B
object into b2
(which I believe is your intention) you can add more brackets
B b2 (( B (A::giveA ()) ));
or use braces (so long as there isn't a constructor that accepts initialiser lists containing a type convertible to type B
)
B b2 {B (A::giveA())};
回答4:
That particular instruction is ambiguous; the way you stated it it may be either a function declaration or a variable definition.
Using extra parentheses should help - it gets unambiguous since you can't declare/call a function with double parentheses:
B b1 = B( A::giveA () ); // works
B b2(( B( A::giveA() ) )); // works for me
B b3( A::giveA() ); // works
Also see here: https://en.wikipedia.org/wiki/Most_vexing_parse
来源:https://stackoverflow.com/questions/44045257/c-compiler-error-c2751-what-exactly-causes-it