2017-05-18 3 views
2

私はC2751コンパイラエラーと対戦しており、正確に何が原因か分かりません。以下の少しのコードではエラーが発生します。私はb2に対して明示的にコンストラクタを呼び出すことはできませんなぜC++コンパイラエラーC2751 - 正確には何が原因ですか?

consoleapplication1.cpp(21): error C2751: 'A::giveA': the name of a function parameter cannot be qualified

:出力

#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 

} 

コンパイラ?

+1

どのコンパイラを使用しますか? gcc 5.4は何の問題もなくコードをビルドしているからです。 – knst

+1

@knst彼はMSVCを使用しています(C2751リンクを参照)。 – vaxquis

+1

@knst [clang](https://wandbox.org/permlink/UajAZ5zfaV8QWmZD)でもコンパイルされません。 – songyuanyao

答えて

6

それはmost vexing parseの問題です。打ち鳴らすの下でコンパイルすると、完全な診断を提供します:

<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 

コンパイラはフィックスにそれを示唆するような操作:

B b2 ((B (A::giveA()))); // no error 
+0

ありがとう、clangの出力は本当に役に立ちました。関数内で関数を宣言することが「許可」されているのはなぜですか?私はそれをしたいと思う状況を本当に考えることができません。 – spinakker

+0

書く方法を想像してみてください: "' b2'は 'B'を返す関数で、引数を取らずに' A :: giveA'を返す関数です " –

2

その特定の命令はあいまいです。あなたがそれを記述した方法は、関数宣言か変数定義のどちらかです。役立つはずの余分な括弧を使用し

- それはあなたが宣言することはできませんので、明確な取得/ダブル括弧で関数を呼び出す:

B b1 = B(A::giveA()); // works 
B b2((B(A::giveA()))); // works for me 
B b3(A::giveA()); // works 

はまたここを参照してください: https://en.wikipedia.org/wiki/Most_vexing_parse

+0

"C-tor /メソッド' B(B b) 'はありません。コンパイラはあなたがそれを呼び出していると思っています。コンパイラは、そのようなコンストラクタを宣言することはできません。あなたがそれを呼んでいるとは思わないでしょう(バグがない限り)。 – cpplearner

+0

@cpplearnerはそれを見つけてくれてありがとう、固定されている。 – vaxquis

2
B b2 (B (A::giveA())); 

あなたがBクラスのコピーコンストラクタを持っていた場合でも、あなたはまだこれを取得したいです上記の行は関数宣言の文法規則に従っているため、エラーです。括弧がB(A::give())の場合、問題は解決します。

2

ああ、問題はmost vexing parseです。

ここ

B b2 (B (A::giveA())); // C2751 

このラインは機能b2Bを返すと、関数型B()A::giveAというパラメータを取るように解釈されます。 C2751エラーは、無効な名前A::giveAによって発生します。修飾名をパラメータ名として使用することはできません。

含むリスト初期化剤受け取るコンストラクタがないとして、あなたがより多くの括弧

B b2 ((B (A::giveA()))); 

を追加したり、あまりにも長い間(中括弧を使用することができます(私はあなたの意図であると信じて)b2への一時的なBオブジェクトをコピーするにはタイプBに変換可能なタイプ

B b2 {B (A::giveA())}; 
関連する問題