25

以这个示例代码为例:

int a = 10;
int b = 20;
int c = 30;

int & foo1() {
    qDebug() << "foo1" << endl;
    return a;
}

int & foo2() {
    qDebug() << "foo2" << endl;
    return b;
}

int & foo3() {
    qDebug() << "foo3" << endl;
    return c;
}

int main(void)
{
    foo1() = foo2() = foo3() = 7;
}

由于分配从右到左,我希望看到foo3第一个和foo1最后一个,但事实恰恰相反。

是否具体定义了此类场景的规则以及如何定义?=此外,编译器是否区分赋值和其他运算符,如果您在与初始化不同的上下文中使用运算符,这怎么可能?也许链分配的处理方式与其他链接不同?

4

3 回答 3

24

完整的表达

foo1() = foo2() = foo3() = 7

可以用以下树进行抽象:

     =
   /   \
foo1()   = 
       /   \
    foo2()   =
           /   \
        foo3()   7

可以按任何顺序评估该树的叶子。您的编译器可以自由选择。只有在调用赋值运算符时,必须首先评估挂在它们上的表达式。在您的情况下,叶子按顺序进行评估foo1()foo2()然后foo3()

的从右到左的关联性=仅在树的形状中可见,而不是在评估顺序中。树为

std::cout << foo1() << foo2() << foo3()

好像

                   << 
                 /    \
              <<      foo3()
            /    \
         <<      foo2()
       /    \
std::cout   foo1()

同样,foo可以以任何顺序评估函数,但评估的顺序operator<<()是明确定义的。有一篇关于序列点的有趣帖子很好地描述了这些主题。

于 2013-06-24T14:58:48.510 回答
15

运算符关联性(即从右到左)与求值顺序无关。* 操作数的评估顺序未指定。


* 除了在少数情况下,&&||,

于 2013-06-24T14:48:16.383 回答
2

评估子表达式的顺序与应用结果的顺序不同!

foo1() 可以提前调用,只是在其他人也完成之前不能应用赋值本身。

于 2013-06-24T14:49:54.063 回答