【问题标题】:Order of execution in operator <<运算符 << 中的执行顺序
【发布时间】:2013-01-26 10:14:56
【问题描述】:

我很难理解下面代码中的调用顺序。 我期待看到下面的输出

    A1B2

虽然我可以看到我得到的输出是

    BA12

我以为调用std::cout&lt;&lt; b-&gt;fooA() &lt;&lt; b-&gt;fooB() &lt;&lt; std::endl就相当于调用

  std::cout.operator<<( b->fooA() ).operator<< ( b->fooB() )

但我可以看到情况并非如此。你能帮助我更好地理解它是如何工作的以及与全球operator&lt;&lt; 的关系吗?这是此序列中最后一次调用的吗?

#include <iostream>

struct cbase{
    int fooA(){
        std::cout<<"A";
        return 1;
    }
    int fooB(){
        std::cout <<"B";
        return 2;
    }
};

void printcbase(cbase* b ){
    std::cout << b->fooA() << b->fooB() << std::endl;
}

int main(){
    cbase b;
    printcbase( &b );
}

【问题讨论】:

  • 您认为它与此等价是正确的。但是,您错误地假设存在明确定义的评估顺序。没有。就是这样。
  • 这里不保证子表达式求值的顺序(它必须是重复的,但我现在找不到一个好的规范问题)
  • AB12BA12 是可能的输出。 A1B2 不是(希望如此)。
  • 不完全重复,但这个问题的答案确实解释了您遇到的未指定顺序。 What is the correct answer for cout << c++ << c;?
  • @jrok 是的,是的。 (假设

标签: c++ stream operator-keyword cout ostream


【解决方案1】:

编译器可以像这样评估函数printcbase()

void printcbase(cbase* b ){
    int a = b->FooA();    // line 1
    int b = b->FooB();    // line 2
    std::cout << a;       // line 3
    std::cout << b;       // line 4
    stc::cout << std::endl;
}

或标记为 1 - 4 的行的许多排列中的一些。您只能保证第 1 行在第 3 行之前完成,第 2 行在第 4 行之前完成(当然第 3 行在第 4 行之前)。标准并没有说更多,实际上您可以期望使用不同的 C++ 编译器得到不同的结果。

【讨论】:

  • 一个约束缺少第 3 行在第 4 行之前。
  • 嗯,这很明显,这不是我的想法。我会添加它。谢谢。
【解决方案2】:

&lt;&lt; 的执行顺序已明确定义,但 C++ 中未定义子表达式的求值顺序。 This article and the C code example 说明了你提到的问题。

BA12AB12 都是正确的。在以下代码中:

std::cout<< b->fooA() << b->fooB()

1 将出现在2 之前,但A 可能出现在B 之前或之后,因为编译器不承诺它是否会首先评估fooAfooB

【讨论】:

    【解决方案3】:

    移位运算符是左结合的; a &lt;&lt; b &lt;&lt; c 被读作(a &lt;&lt; b) &lt;&lt; c,这意味着如果a 属于用户定义的operator&lt;&lt; 成员类型(并返回该类型),则表达式读作a.operator&lt;&lt;(b).operator&lt;&lt;(c)。如果改为使用免费的operator&lt;&lt;,则读取为operator&lt;&lt;(operator&lt;&lt;(a, b), c)

    所以a &lt;&lt; b的评估在(a &lt;&lt; b) &lt;&lt; c的评估之前被排序,但是bc的评估之间没有排序依赖关系:

    a << b << c[1]
    |         |
    a << b[2] |
    |    |    c[5]
    a[3] b[4]
    

    如果我们像上面那样对副作用进行编号,那么副作用可以按以下顺序排列:

    54321
    53421
    45321
    43521
    43251
    35421
    34521
    34251
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-17
      • 2011-08-01
      • 1970-01-01
      • 2017-04-17
      • 2016-01-24
      • 1970-01-01
      • 2023-03-29
      相关资源
      最近更新 更多