C ++ STL字符串运算符+关联性

时间:2017-02-07 14:09:17

标签: c++ operator-precedence associativity

我在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+?我是否陷入了一些误解?

2 个答案:

答案 0 :(得分:8)

您在associativityorder or evaluation之间感到困惑。

在C ++中未指定参数的评估顺序。正如您所提到的,operator +的相关性是从左到右。

要理解这一点,请尝试使用operator -

的类似代码段

来自Order or evaluation(强调我的)

  

除非下文所述,否则没有从左到右或从左到右的概念   C ++中从右到左的评估。 这是不要混淆的   从左到右和从右到左的运营商关联性:   表达式f1()+ f2()+ f3()被解析为(f1()+ f2())+ f3()由于   operator +的从左到右的关联性,但函数调用f3   可以在运行时第一次,最后一次或在f1()或f2()之间进行评估。

答案 1 :(得分:4)

您假设编译器在执行加法运算符之前为函数调用发出代码。这不一定是真的。实际的操作顺序可以是:

  1. 调用栏(30),保存结果。
  2. 调用栏(20),保存结果。
  3. 调用栏(10),保存结果。
  4. 添加步骤3和步骤2的结果。
  5. 添加步骤4和步骤1的结果。
  6. 当然,由于加法是对称的,加法的顺序实际上并不重要。

    在这种情况下,C ++不要求函数调用立即与加法一起发生。管理评估顺序的规则实际上非常复杂。可以这么说,在这种情况下,没有指定函数调用的顺序,并且每个C ++实现都可以以任何相对顺序进行函数调用。事实上,每次运行程序时相对顺序可能不同(当然不太可能,但这仍然是合规的)。