C での STL メソッドの連鎖は評価順序を保持しますか?
Bjarne Stroustrup の『The C Programming Language』第 4 版では、次のコード スニペットが示されています。メソッドチェーンの例:
<code class="cpp">void f2() { std::string s = "but I have heard it works even if you don't believe in it"; s.replace(0, 4, "").replace(s.find("even"), 4, "only").replace(s.find(" don't"), 6, ""); assert(s == "I have heard it works only if you believe in it"); }</code>
このコードはステートメントを左から右に評価し、文字列 s を段階的に変更します。ただし、この式の動作は使用するコンパイラによってあいまいです:
不特定の動作を明らかにする
コードは、不定なため、不特定の動作を示します。未定義の動作を呼び出さないにもかかわらず、部分式の評価順序。問題の核心は、連鎖関数呼び出し内の関数引数の評価順序にあります。
特に次の部分式の場合:
それらの評価順序は次に関して不定です:
これは、find 呼び出しが replace 呼び出しの前後で評価され、 s の長さに影響を及ぼし、その結果、find 呼び出しの結果を変更できることを意味します。
カスタム検索関数を使用した図
この曖昧さを示すために、コードの修正バージョンでは、各部分式の評価における検索文字列の位置を報告するカスタム my_find 関数を使用します。
<code class="cpp">std::string::size_type my_find(std::string s, const char *cs) { std::string::size_type pos = s.find(cs); std::cout << "position " << cs << " found: " << pos << std::endl; return pos; }</code>
このコードを異なるコンパイラで実行すると、評価順序に応じて異なる結果が得られます:
C 17 の変更
C 17 標準 (p0145r3) では、この曖昧さに対処するために式の評価順序ルールに改良が導入されています。次のように、後置式とその式リストの評価順序が強化されます。
これにより、連鎖メソッド呼び出しが期待された順序で評価されるようになり、C 17 でのこの未定義の動作が解決されます。
以上がSTL メソッド チェーンは C での評価順序を維持しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。