C++ Compiler Error C2751 - What exactly causes it?

久未见 提交于 2019-12-24 06:29:51

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!