2012-04-02 19 views
22

アプリケーションの開発中に、次の問題がありました。与えられた関数ポインタがnullの場合は空のstd::list<string>を返すか、そうでない場合はその関数の結果を返したいと思います。私は通常、これらの場合に三元(?:)演算子を使用したい、しかし3進演算子+ C++ 11 initializer_listのコンストラクタ

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から自分のコンストラクタを使用して作成されたオブジェクトを返すように三項演算子を使用することはできませんでしょうか?何か特別な理由はありますか?

+1

私のアドバイスは次のようなものです:**これはまったく行いません**。イテレータ(その型はテンプレートパラメータです)をとる汎用的なアルゴリズムにしてください。そうすれば、 'std :: list'が悪い選択であると分かったときに、比較的無痛に何かに変更することができます。 –

+0

@JerryCoffinおそらくその助言を取るでしょう;)。私はそれがとにかく(それができない場合それができない場合はなぜ)可能かどうかを知りたいです。 – mfontanini

+0

さて、十分に公正。正確なアプリケーションがおそらく最善ではないと思うにしても、面白い質問です。 –

答えて

15

標準は、8.5.4.1に書いている:リスト初期化それらの

Note: List-initialization can be used

  • as the initializer in a variable definition (8.5)
  • as the initializer in a new expression (5.3.4)
  • in a return statement (6.6.3)
  • as a function argument (5.2.2)
  • as a subscript (5.2.1)
  • as an argument to a constructor invocation (8.5, 5.2.3)
  • as an initializer for a non-static data member (9.2)
  • in a mem-initializer (12.6.2)
  • on the right-hand side of an assignment (5.17)

何もすることは三項演算子です。よりミニマルなreturn 1?{}:{};も無効ですが、あなたが望むものは不可能です。もちろん

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

+0

素晴らしい、それは私が探していた正当な理由でした。 – mfontanini

3

{}を実行すると、コンパイラは予期している型を知らないため、コンパイラが何をすべきか分からないという無意味な表現に過ぎません。 :の両側は別々に評価され、型が一致しない場合にのみ、コンパイラが文句を言います。私はこれを行うだろう:

return generator ? generator() : std::list<std::string>(); 
2

あなたが本当に三項演算子のように、あなたはこのような何かを試すことができた場合:

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

後で戻り値の型を変更した場合、それも動作します。