これがコンパイルされる理由がわかりません


80

私は確かに何かを見逃していますが、これが(g ++とclang ++の両方で)コンパイルされる理由がわかりません:

struct A
{
};
struct B
{
};

int main()
{
  A a(B);
}

まず第一にB、型です...値ではありません。このコードをどのように解釈すればよいですか?


37
これは最も
厄介な

8
@alterigelほんと?この場合、あいまいさはありません。関数宣言のみが可能です。A a(B());変数の定義や関数の宣言ではありません。
クルミ

8
何も名前を付けていなくても、struct A{}; int main() { A(foo); } そのままコンパイルできることを知って驚かれることでしょうfoo
Ayxan

20
@alterigel-これは最も厄介な解析ではありません。リンクしたページの例を見てください。これは単に関数宣言です。
ピートベッカー

3
@PeteBecker、これがMVPではない理由を説明したほうがいいのではなく、MVPでないことを主張するだけの方が良いかもしれません。
JPhi1618

回答:


84

これは、という名前の関数の宣言として解釈され、a型の引数を1つ取り、をB返しますA


5
そしてそれこそが、Most and Vexingなのです。解決策:(悪い構造を明らかにしているため、実際には何かを解決するわけではありません)A a{B};
user4581301

23
@ user4581301- 最も厄介な解析ではありません。それは単に関数宣言です。
ピートベッカー

23
つまり、これはほとんど厄介な解析にすぎないことわかります...
MooseBoys

11
それについての奇妙な部分はC ++はネストされた関数を許可していませんが、ということである関数の中で宣言を可能にします。
The_Sympathizer

6
入れ子関数のサポートをC ++に追加する動機のように思えます。それらは有用であるだけでなく、この奇妙ないぼを合理的なデザインに変えます:)
Jeremy Friesner

15

これは単に、型の名前のないパラメータを1つa返して受け取る関数であることを宣言する関数宣言です。AB

関数定義ではなく関数宣言が関数定義内で許可されているため、これは有効です。


13

この問題は、最も厄介な解析として知られています。この行A a(B);a、型のオブジェクトを返し、型Aの名前のないパラメーターを受け取るという名前の関数の宣言として解釈できますB

この問題を回避する1つの方法は、C ++ 11で導入された、括弧の代わりに中括弧を使用することで構成される統一された初期化構文を使用A a{B};することです。エラーを返します。行はB、値ではなく型であるで初期化された変数宣言として解釈されるようになりました。

詳細は次のとおりです。

最も厄介な解析:それを見つけてすばやく修正する方法


12
これは「最も厄介な解析」と呼ばれるべきではないと私は思います。Cにも存在するため、これは通常の関数宣言にすぎません。行は関数宣言のみであり、それ以外は何もないため、あいまいさの解決は必要ありません。あなたのリンクを見てください。例はすべてこれとは異なります。
ウォールナット

3
それは事実ですが、最も厄介な解析に関連しています。たぶん元の意図どおり、変数またはコンストラクター呼び出しの代わりにタイプ名が単独で使用されたタイプミスも含まれているだけです。
ミラル

1
ええ、「Most Vexing Parse」は問題の実際のケースが「わずかにVexing Parse」であるにもかかわらず、このケースでは有用な回答です。
jpa

1
@wlanut:空の構造 struct A { };は、一部のコンパイラーで許可されている場合でも、標準Cでは無効です。中かっこをドロップすると、そこに問題はありません。また、Cでは、宣言または定義struct Aしても型名は作成されませんA(接頭辞struct、または接頭辞なしで使用するtypedef struct A A;前にどこかに追加する必要があります)。また、Cでは、関数宣言に代わる解析はありません。単に使用するだけで変数定義になることはありません。常に関数宣言です(または無効です)。問題のコードはCで有効ではありませんAstructtype name(...);
ジョナサン・レフラー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.