32

アプリケーションの開発中に、次の問題が発生しました。std::list<string>特定の関数ポインタが null の場合は空を返し、それ以外の場合はその関数の結果を返したいと考えていました。これは私のコードの簡略版です:

typedef std::list<std::string> (*ParamGenerator)();

std::list<std::string> foo() {
    /* ... */
    ParamGenerator generator = ...;
    if(generator)
        return generator();
    else
        return {};
}

ただし、?:これらの場合は通常、三項 ( ) 演算子を使用するのが好きなので、このように使用してみました (いつものように):

return generator ? generator() : {};

しかし、このエラーが発生しました:

somefile.cpp:143:46: error: expected primary-expression before ‘{’ token
somefile.cpp:143:46: error: expected ‘;’ before ‘{’ token

これは、三項演算子を使用して、コンストラクターを使用して作成されたオブジェクトを返すことができないということinitializer_listですか? それには何か特別な理由がありますか?

4

4 に答える 4

25

8.5.4.1での標準書き込み:リストの初期化

注:リストの初期化を使用できます

  • 変数定義の初期化子として(8.5)
  • 新しい式の初期化子として(5.3.4)
  • returnステートメント(6.6.3)
  • 関数の引数として(5.2.2)
  • 下付き文字として(5.2.1)
  • コンストラクター呼び出しの引数として(8.5、5.2.3)
  • 非静的データメンバーの初期化子として(9.2)
  • mem-initializer(12.6.2)で
  • 割り当ての右側(5.17)

それらのどれも三項演算子ではありません。よりミニマルreturn 1?{}:{};なものも無効であり、あなたが望むことは不可能です。

もちろん、コンストラクターを明示的に呼び出すこともできますが、すでに行ったように---ブロックstd::list<std::string>{}を書き出すことをお勧めしifます。else

于 2012-04-02T19:56:24.780 に答える
9

あなたがそう{}するとき、コンパイラーはあなたが期待している型の知識を持っていないので、コンパイラーが何をすべきか分からないのは無意味な式です. の両側が:別々に評価され、型が一致しない場合にのみコンパイラが文句を言います。私はこれを行うだけです:

return generator ? generator() : std::list<std::string>();
于 2012-04-02T19:48:06.437 に答える
2

三項演算子が本当に好きなら、次のようなことを試すことができます。

return generator ? generator() : decltype(generator()) { "default value", "generator was empry" };

後で戻り値の型を変更しても機能します。

于 2012-04-02T20:36:33.173 に答える