C++ STL字符串operator+的结合性

4

我在 VC++ 2015 中尝试了以下代码

#include <iostream>
#include <string>

using namespace std;

int foo(int v)
{
    cout << v << endl;
    return 10;
}

string bar(int v)
{
    cout << v << endl;
    return "10";
}

int main()
{
    auto a = foo(1) + foo(2) + foo(3);
    auto b = bar(10) + bar(20) + bar(30);
    cout << "----" << endl << a << endl << b << endl;
    return 0;
}

控制台的结果如下所示。
1
2
3
30
20
10
----
30
101010

众所周知,二进制+运算符具有左到右的结合性,并且可以通过对foo的三次调用进行确认。它们按照指令顺序从左到右被调用。 我的问题是,为什么这似乎对string::operator+不适用?我是否有一些误解?
2个回答

8
你可能会混淆 结合律运算顺序或求值顺序
在C++中,参数的求值顺序是未指定的。正如你所提到的那样,operator + 的结合性是从左到右的。
为了理解这一点,可以尝试使用类似的代码片段来测试 operator -

来自订单或评估(我强调)

除非下面有说明,否则在C++中没有左到右或右到左的求值概念。 这与运算符的左到右和右到左的结合性不同:表达式f1()+f2()+f3()由于operator+的左到右结合性被解析为(f1()+f2())+f3(),但是对f3的函数调用可能在运行时首先、最后或在f1()或f2()之间进行评估。


4
你假设编译器在执行加法运算符之前会发出函数调用的代码。但这并不一定正确。实际操作顺序可以简单地是:
  1. 调用bar(30),保存结果。
  2. 调用bar(20),保存结果。
  3. 调用bar(10),保存结果。
  4. 将步骤3和步骤2的结果相加。
  5. 将步骤4和步骤1的结果相加。
当然,由于加法是对称的,加法顺序实际上并不重要。
在这种情况下,C++不要求函数调用与加法立即结合。评估顺序的规则实际上非常复杂。可以简单地说,在这种情况下,函数调用的顺序未指定,每个C++实现都可以按任何相对顺序进行函数调用。实际上,每次运行程序时,相对顺序可能不同(当然这很少见,但这仍然是合规的)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接