2

このコードで C++ の文字列をトリムしたい:

std::string str("  Trim test   ");
str.erase(                                 /* 1 */
          0,                               /* 2 */
          str.find_first_not_of(" ")       /* 3 */
         )                                 /* 4 */
   .erase(                                 /* 5 */
          str.find_last_not_of(" ") + 1,   /* 6 */
          std::string::npos                /* 7 */
         );                                /* 8 */

標準では、行 #1 が実行される前に行 #6 を計算できるので、#5 が最終的に呼び出されたときに引数が無効になる可能性がありますか?

4

2 に答える 2

3

はい、標準では、行#1が実行される前に行#6を計算できます。

シーケンスポイントに関するウィキペディアのページから:

[シーケンスポイントが発生します]関数が関数呼び出しに入力される前。引数が評価される順序は指定されていませんが、このシーケンスポイントは、関数が入力される前にすべての副作用が完了することを意味します。式f(i ++)+ g(j ++)+ h(k ++)では、fは元の値iのパラメーターで呼び出されますが、iはfの本体に入る前にインクリメントされます。同様に、jとkは、それぞれgとhを入力する前に更新されます。ただし、f()、g()、h()が実行される順序や、i、j、kがインクリメントされる順序は指定されていません。fの本体の変数jとkは、すでにインクリメントされている場合とされていない場合があります。関数呼び出しf(a、b、c)はコンマ演算子の使用ではなく、a、b、およびcの評価の順序は指定されていないことに注意してください。

次のように書き直す必要があります

str.erase(0, str.find_first_not_of(" "));           

str.erase(str.find_last_not_of(" ") + 1, std::string::npos);     
于 2011-10-26T22:11:50.477 に答える
1

はい、6 は 1 の前に呼び出される場合があります。

ただし、コードは問題にならないように再配置できます。

std::string str("  Trim test   ");
str.erase(                                 /* 1 */
          str.find_last_not_of(" ") + 1,   /* 2 */
          std::string::npos                /* 3 */
         )                                 /* 4 */
   .erase(                                 /* 5 */
          0,                               /* 6 */
          str.find_first_not_of(" ")       /* 7 */
         );                                /* 8 */

7 が 1 の前に呼び出されないという保証はありませんが、インデックスはまだ有効であるため問題ありません。
覚えておいてください、これを 1 行で行うのは良くない考えであり、少なくとも 4 行に分ける必要があります。

于 2011-10-26T22:46:40.800 に答える