4

私は次のコードを持っています:

enum nums {
  a
};

class cls {
public:
  cls( nums );
};

void function()
{
  cls( a );
}

gcc でコンパイルしようとすると、次のエラーが発生します。

test.cpp: In function ‘void function()’:
test.cpp:12:10: error: no matching function for call to ‘cls::cls()’
test.cpp:12:10: note: candidates are:
test.cpp:7:3: note: cls::cls(nums)
test.cpp:7:3: note:   candidate expects 1 argument, 0 provided
test.cpp:5:7: note: cls::cls(const cls&)
test.cpp:5:7: note:   candidate expects 1 argument, 0 provided
make: *** [test] Error 1

関数をこれに置き換えると:

void function()
{
  cls name( a );
}

その後、すべてが機能します。2 つの引数を持つコンストラクターを使用する場合にも機能します。コンストラクターに「明示的」を追加すると機能しません。

gcc は何らかの形でこれを「cls」型の変数を「a」という名前で定義するものとして解析していることがわかりますが、変数を定義するためのそのような構文には慣れていません。私の目には、これは cls 型の匿名一時変数を定義するステートメントであり、「a」をパラメーターとして渡します。

gcc 4.6.3 でコンパイル。

洞察はありますか?

ありがとう、シャチャー

4

2 に答える 2

10

最も厄介なパースの問題の別の例。この線:

cls( a );

atypeという名前のローカル変数を宣言しますcls。これは、デフォルトのコンストラクターを呼び出すことによって初期化されます (または初期化する必要があります)。エラーメッセージが表示されるため、存在しません。

直後に破棄される一時オブジェクトを本当に構築したい場合は、式全体を括弧で囲むことであいまいさを取り除くことができます。

(cls( a ));

括弧内に定義を記述することはできません。式はできます。

于 2013-07-11T13:05:59.993 に答える
8

括弧はオプションです。これcls (a);は、型cls a;のオブジェクトを宣言し、それ をデフォルトで初期化します (一致するコンストラクターがないため失敗します)。acls

cls { a };式の最後で有効期限が切れる一時的な値を作成するには、C++11 で or (cls(a));(または のような難解な構造体をいくつでも)と言えますvoid(0), cls(a);

その他のアイデアについては、この回答を参照してください。

于 2013-07-11T13:04:51.170 に答える