演算子式の初期化子リスト: ジレンマ
C では、中括弧で囲まれた初期化子リストが変数を初期化する便利な方法を提供します。 。ただし、演算子式で初期化子リストを使用しようとすると、興味深い疑問が生じます。次のコードを考えてみましょう。
class foo { }; struct bar { template<typename... T> bar(T const&...) { } }; foo& operator<<(foo& f, bar const&) { return f; } int main() { foo baz; baz << {1, -2, "foo", 4, 5}; // This line gives an error return 0; }
このコードでは、特に式 baz << を含む行に関してエラーが発生するのはなぜですか。 {1, -2, "foo", 4, 5};?その理由は、C 標準の初期化子リストの定義にあります。
初期化子リスト: 式の例外
標準の §5 では、式が正確に定義されています。驚くべきことに、初期化子リストは式そのものとはみなされません。 << を含む二項演算子は、引数として式を期待します。したがって、初期化子リストはこの基準を満たさないため、二項演算子のオペランドとして直接使用することはできません。
限定的な例外
標準では、初期化子に対していくつかの例外が用意されています。関数の引数や代入ステートメントでのリストの使用法など。ただし、例外は二項演算子には適用されません。
制限の理由
この制限の根拠は多岐にわたります。草案/ディスカッション ペーパー N2215 によると、初期化子リストを演算子の左側と右側の両方のオペランドとして許可すると、パーサーに課題をもたらす文法的な複雑さが生じる可能性があります。この論文の著者は最終的に、右側では許可するが、左側では許可しないのは面倒すぎると判断しました。
結論
while 初期化子リスト特定のコンテキストでは利便性を提供しますが、演算子の右側での使用が制限されているのは、構文上の課題と言語の文法の一貫性への要望から生じています。オペランドとして初期化子リストを使用する代わりに、次の変更されたコードに見られるように、コンストラクターの呼び出しを使用するか、bar インスタンスを引数として演算子<<() に直接渡すことができます:
baz << bar{1, -2, "foo", 4, 5};
以上が初期化子リストを C の二項演算子式のオペランドとして直接使用できないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。