Eraseâremove idiom
:
v.erase( std::remove_if(v.begin(), v.end(), is_odd), v.end() );
根据我对评估顺序的了解,
v.end()
(在rhs上)可能会被评估
之前
std::remove_if
. 这不是问题,因为
std::remove*
只洗牌向量而不更改其结束迭代器。
但它可能会导致非常令人惊讶的构造,例如(
demo
):
#include <iostream>
struct Data
{
int v;
int value() const { return v; }
};
auto inc(Data& data) { return ++data.v; }
void print_rhs(int, int value) { std::cout << value << '\n'; }
int main()
{
Data data{0};
print_rhs(inc(data), data.value()); // might print 0
}
这是令人惊讶的,因为
print_rhs
被称为
之后
inc
被称为;意思是
data.v
是
1
印刷品
被称为。尽管如此,因为
data.value()
之前
,
0
我认为,如果计算顺序不那么令人惊讶的话,这可能是一个很好的改进;特别是如果一个有副作用的函数的参数在没有副作用的函数的参数之前被计算出来的话。
我的问题是:
-
在C++委员会中讨论过或建议过这种改变吗?
-
你看到它会带来什么问题吗?