4

これはMost bexing parse: why doesn't A a(());の複製ではありません。仕事?の形式の解析に基づいており、その OPは、余分な括弧のセットを使用してオブジェクトをA a(());デフォルトで構築できると考えていました。A

f対照的に、私の質問は 2 つのクラスgについてfです。統一された初期化構文を使用せずに、一時的な引数を指定して の ctorを呼び出したい。のctor にステートメントがあるため、出力がないことは、オブジェクトのインスタンス化ではなく、関数宣言を意味します。コメントでサンプルコードに 3 つの数字で注釈を付けました。#1 と #2 は #3 をコメントアウトしてコンパイルされ、その逆も同様です。gfgfstd::coutgg

#include <iostream>
struct f {};
struct g {
    g(f) { std::cout << "g's ctor\n"; }
};
int main() {
                          // -----Output-----
    g( f() );             // #1: function declaration; expected
    g( ( f() ) );         // #2: also a function declaration; UNEXPECTED
    // g myG( ( f() ) );  // #3: "g's ctor" ONLY if #1 & #2 are commented out;
                          //     ^ ... linker error otherwise
}

#1: #1gは、 a を返し、0 引数を取り、 an を返す関数へのポインターを受け取る無名関数を宣言していると思いましたf。私が間違っている?

#2: #2の余分な括弧のセットにより、囲まれた内容が関数呼び出し、つまりfのデフォルト ctor への呼び出しとして評価されるようになると思いました。しかし、それはまだ関数宣言です。なんで?

#3: #2 の変形で、違いは #3 の追加されたインスタンス名myGです。#1 と #2 がコメントアウトされている場合、#3 はオブジェクトをインスタンス化します。そうしないと、VC12 で次のエラーが発生します。

error LNK2019: unresolved external symbol "struct g __cdecl f(void)" (?f@@YA?AUg@@XZ) referenced in function _main

fatal error LNK1120: 1 unresolved externals.

g ++ 4.8でのこのエラー:undefined reference to 'f()'

それらは何を意味し、なぜ私はそれらを得るのですか?

インスタンスに名前が付けられている場合にのみ #3 がオブジェクトのインスタンス化になるのはなぜですか?

インスタンスに名前を付けたり、均一な初期化を使用したりせずに、目的のインスタンス化効果を得るにはどうすればよいですか?

4

1 に答える 1

7

f最初のものは、パラメータをとらず、 を返す関数を宣言していますg

     g( f() );
  //  ^     ^  redundant set of parentheses

2 番目のものは同じですが、さらに別の冗長な括弧のセットがあります (同じ関数の宣言は必要な数だけ持つことができることに注意してください)。ただし、それらは常に役に立たないわけではありません。たとえば、関数ポインターを返す関数を宣言するために必要です。

// function taking an int and returning
// a pointer to a function that takes a char
// and returns a g
g ( *f(int) )(char);
//^         ^ needed, syntax error without them

3番目について:

#1 と #2 がある場合、 in の関数宣言がfありmain、関数呼び出しの結果で名前が付けられ、初期化されg myG( ( f() ) );た type のオブジェクトの宣言として解析されます。の定義がないため、リンカー エラーが発生します。gmyGf

#1 と #2 がコメント アウトされると、型fが表示され、括弧による曖昧さの解消が開始されます。

g myG( ( f() ) )
//     ^     ^   these force an expression

そのペアがないと、別の関数宣言が得られます。

あなたが欲しいのはこれです:

   ( g(f()) );
// ^        ^  must be an expression as declarations can't be parenthesized

またはそれ以下のLisp-y: static_cast<g>(f());

于 2013-12-18T01:23:16.950 に答える