分配顺序与初始化顺序

时间:2013-06-24 14:45:33

标签: c++ initialization assignment-operator chaining

以此示例代码:

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,但情况正好相反。

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

3 个答案:

答案 0 :(得分:24)

完整的表达

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

可以使用以下树抽象:

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

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

=的右到左关联只能在树的形状中看到,而不是按照评估的顺序。

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

看起来像

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

同样可以按任何顺序评估foo函数,但operator<<()的评估顺序是明确定义的。有一个有趣的post about sequence points可以很好地描述这些主题。

答案 1 :(得分:15)

操作员关联性(即从右到左)与评估订单无关。 * 操作数的评估顺序未指定。

<小时/> *除少数情况外,即&&||,

答案 2 :(得分:2)

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

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