4

次の問題がわかりません。

class InnerBox
{
public:
    InnerBox() : mContents(123) { };
private:
    int mContents;
};


class Box
{
public:

    Box(const InnerBox& innerBox) : mInnerBox(innerBox) { };

private:
    InnerBox mInnerBox;
};


void SomeFunction(const Box& box)
{
    return;
}

int main()
{
    Box box(InnerBox());  // !!PROBLEM!! Doesn't work: compiler thinks this is a function declaration
    SomeFunction(box);    // Error, cannot convert 'function pointer type' to const Box&

    return 0;
}

完全なエラー メッセージは (Visual Studio 2010)

 error C2664: 'SomeFunction' : cannot convert parameter 1 from 'Box (__cdecl *)(InnerBox (__cdecl *)(void))' to 'const Box &'

修正は簡単です:

int main()
{
    InnerBox innerBox;
    Box box(innerBox);  
    SomeFunction(box);

    return 0;
 }

これは MSVC 固有の問題Box box(InnerBox());ですか。

4

3 に答える 3

5

次のように記述する必要があります。

Box box((InnerBox()));

また

Box box{InnerBox()};

これは MSVC 固有の問題ではありません。C++ のルールは、宣言である可能性のある構造を宣言と見なすことです。

追加のかっこがない場合、コードは、boxを返す関数を宣言してBoxおり、その単一の引数は、引数をとらず、 を返す関数へのポインタInnerBoxです。(はい --関数パラメーターで使用される場合、実際には関数 (名前なし) へのポインターを宣言します (これは、関数パラメーターとして使用される場合にポインターを実際に宣言するInnerBox()方法と似ています))。Box[]Box

于 2012-08-15T00:29:59.990 に答える
5

元の like は、Box を返し、InnerBox を返し、パラメータをとらない関数ポインタをパラメータとして受け取る「box」という名前の関数の関数宣言(定義InnerBox (*)()ではなく) として解析されています。Most Vexing Parse 問題の適切な説明については、これを参照してください。

追加の括弧を使用して、オブジェクトの構築を明示的に区別できますBox box((InnerBox()));。または、もう少しクリーンな代替手段として、新しい C++11 オブジェクト構築構文を使用できます。

Box box{InnerBox()};

于 2012-08-15T00:33:32.560 に答える
4

これは MSVC 固有の問題ですか。そうでない場合は、Box box(InnerBox()); の呼び出しを妨げている言語の癖を誰かが説明できますか? ?

他の回答を完了するには:

これは、最も厄介な解析として知られています。コンパイラの問題ではありません。これは基本的に、宣言として扱うことができるものはすべて宣言として扱うという構文解析仕様です。

あなたの場合、あなたはそれを修正することができます

Box box((InnerBox()));
于 2012-08-15T00:36:57.273 に答える