在operator <<中执行的顺序

Abr*_*ile 11 c++ cout stream ostream operator-keyword

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

    A1B2
Run Code Online (Sandbox Code Playgroud)

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

    BA12
Run Code Online (Sandbox Code Playgroud)

我认为这个电话std::cout<< b->fooA() << b->fooB() << std::endl相当于电话

  std::cout.operator<<( b->fooA() ).operator<< ( b->fooB() )
Run Code Online (Sandbox Code Playgroud)

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

问候

AFAG

#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 );
}
Run Code Online (Sandbox Code Playgroud)

mit*_*ity 10

编译器可以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;
}
Run Code Online (Sandbox Code Playgroud)

或者标记为1 - 4的许多线条的一些.只保证第1行在第3行之前完成,第2行在第4行之前完成(当然第4行在第4行之前).标准没有说更多,实际上你可以期望不同的C++编译器得到不同的结果.


Sal*_*n A 6

执行的顺序<<是明确定义的,但子表达式的评估顺序没有在C++中定义.本文和C代码示例说明了您提到的问题.

BA12并且AB12都是正确的.在以下代码中:

std::cout<< b->fooA() << b->fooB()
Run Code Online (Sandbox Code Playgroud)

1会出现之前2,但A之前或之后可能出现B,因为编译器不保证它是否会评估fooA或fooB第一.


eca*_*mur 5

移位运算符是左结合的;a << b << c读作(a << b) << c,这意味着如果a是具有用户定义成员的类型operator<<(并返回该类型),则表达式读作a.operator<<(b).operator<<(c)。operator<<如果改为使用free ,那么这将读作operator<<(operator<<(a, b), c) ,则其读作。

因此, 的计算顺序a << b先于 的计算顺序,但和(a << b) << c的计算之间不存在顺序依赖性:bc

a << b << c[1]
|         |
a << b[2] |
|    |    c[5]
a[3] b[4]
Run Code Online (Sandbox Code Playgroud)

如果我们按照上面的方式对副作用进行编号,那么副作用可以按以下任意顺序排序:

54321
53421
45321
43521
43251
35421
34521
34251
Run Code Online (Sandbox Code Playgroud)