我在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
的3次调用来确认。他们按指令顺序从左到右调用。
我的问题是,为什么这似乎不适用于string::operator+
?我是否陷入了一些误解?
答案 0 :(得分:8)
您在associativity和order or evaluation之间感到困惑。
在C ++中未指定参数的评估顺序。正如您所提到的,operator +
的相关性是从左到右。
要理解这一点,请尝试使用operator -
来自Order or evaluation(强调我的)
除非下文所述,否则没有从左到右或从左到右的概念 C ++中从右到左的评估。 这是不要混淆的 从左到右和从右到左的运营商关联性: 表达式f1()+ f2()+ f3()被解析为(f1()+ f2())+ f3()由于 operator +的从左到右的关联性,但函数调用f3 可以在运行时第一次,最后一次或在f1()或f2()之间进行评估。
答案 1 :(得分:4)
您假设编译器在执行加法运算符之前为函数调用发出代码。这不一定是真的。实际的操作顺序可以是:
当然,由于加法是对称的,加法的顺序实际上并不重要。
在这种情况下,C ++不要求函数调用立即与加法一起发生。管理评估顺序的规则实际上非常复杂。可以这么说,在这种情况下,没有指定函数调用的顺序,并且每个C ++实现都可以以任何相对顺序进行函数调用。事实上,每次运行程序时相对顺序可能不同(当然不太可能,但这仍然是合规的)。