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++) 中,使用 i 的原始值的参数调用 f,但在进入 f 的主体之前 i 会增加。类似地,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

是的,可以在 1 之前调用 6。

但是,可以重新排列代码以使其无关紧要:

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 之前被调用,但这并不重要,因为索引仍然有效。
请记住,在一行上写这么多是个坏主意,至少应该是 4 个单独的行。

于 2011-10-26T22:46:40.800 回答