C++ STL 字符串运算符+结合性
C++ STL string operator+ 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+
?我是不是误会了什么?
你对associativity and order or evaluation感到困惑。
参数的求值顺序在 C++ 中未指定。如您所述,operator +
的关联性是从左到右。
要了解这一点,请使用 operator -
尝试类似的代码片段
来自 Order or evaluation(强调我的)
Except where noted below, there is no concept of left-to-right or
right-to-left evaluation in C++. This is not to be confused with
left-to-right and right-to-left associativity of operators: the
expression f1() + f2() + f3() is parsed as (f1() + f2()) + f3() due to
left-to-right associativity of operator+, but the function call to f3
may be evaluated first, last, or between f1() or f2() at run time.
您假设编译器在执行加法运算符之前为函数调用发出代码。这不一定是真的。实际的操作顺序可以简单地是:
- 调用bar(30),保存结果。
- 调用bar(20),保存结果。
- 调用bar(10),保存结果。
- 将第 3 步和第 2 步的结果相加。
- 将第 4 步和第 1 步的结果相加。
当然,因为加法是对称的,所以加法的顺序并不重要。
在这种情况下,C++ 不要求函数调用与加法一起立即发生。管理评估顺序的规则实际上非常复杂。可以这么说,在这种情况下,函数调用的顺序没有指定,每个 C++ 实现都可以以任何相对顺序进行函数调用。事实上,每次你 运行 程序时,相对顺序都可能不同(当然不太可能,但这仍然是合规的)。
我在 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+
?我是不是误会了什么?
你对associativity and order or evaluation感到困惑。
参数的求值顺序在 C++ 中未指定。如您所述,operator +
的关联性是从左到右。
要了解这一点,请使用 operator -
来自 Order or evaluation(强调我的)
Except where noted below, there is no concept of left-to-right or right-to-left evaluation in C++. This is not to be confused with left-to-right and right-to-left associativity of operators: the expression f1() + f2() + f3() is parsed as (f1() + f2()) + f3() due to left-to-right associativity of operator+, but the function call to f3 may be evaluated first, last, or between f1() or f2() at run time.
您假设编译器在执行加法运算符之前为函数调用发出代码。这不一定是真的。实际的操作顺序可以简单地是:
- 调用bar(30),保存结果。
- 调用bar(20),保存结果。
- 调用bar(10),保存结果。
- 将第 3 步和第 2 步的结果相加。
- 将第 4 步和第 1 步的结果相加。
当然,因为加法是对称的,所以加法的顺序并不重要。
在这种情况下,C++ 不要求函数调用与加法一起立即发生。管理评估顺序的规则实际上非常复杂。可以这么说,在这种情况下,函数调用的顺序没有指定,每个 C++ 实现都可以以任何相对顺序进行函数调用。事实上,每次你 运行 程序时,相对顺序都可能不同(当然不太可能,但这仍然是合规的)。