C ++ compiler error C2751 - What exactly is causing it?
I am struggling with compiler error C2751 and am not quite sure what exactly is causing it. The following small code throws an 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 explicitly call the constructor for b2
?
source to share
This is the most troublesome parsing problem . Compiling for clang gives full diagnostics:
<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
Execution as the compiler suggests to fix it:
B b2 ((B (A::giveA ()))); // no error
This particular instruction is ambiguous; then as you stated it could be either a function declaration or a variable definition.
Using extra parentheses should help - it becomes unambiguous since you cannot declare / call a function with double brackets:
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
source to share
Ah, the ol problem is the most troublesome parsing .
This line is here
B b2 (B (A::giveA ())); // C2751
interpreted as a function b2
that returns B
and accepts a function A::giveA
type parameter B()
. Error C2751 is caused by an invalid name A::giveA
: You cannot use a qualified name as a parameter name.
To copy the temporary object B
to b2
(which I believe is your intention) you can add more brackets
B b2 (( B (A::giveA ()) ));
or use curly braces (as long as no constructor exists that accepts initialization lists containing the type of the type being converted B
)
B b2 {B (A::giveA())};
source to share