我了解到,当我调用
之类的函数时a(b(),c());
然后,此行为可能在<= C ++ 14中未定义,而在> = C ++ 17中未指定,这是由编译器确定是评估b
还是{ {1}}首先。
我想知道强制执行评估命令的最佳方法。我将编译为C ++ 14。
立即想到的是这样的东西:
c
我是否处于不确定的行为状态?或者这是如何“强制”执行评估命令的?
答案 0 :(得分:27)
用于分隔语句的分号强加了“在发生之前”的关系。
必须首先评估auto && a = increment()
。这是有保证的。在第二次调用a
之前,返回的临时文件将绑定到引用increment
(并延长了其寿命)。
没有UB。这是强制执行评估命令的 方法。
这里唯一的问题是如果increment
本身返回了引用,那么您就需要担心生命周期问题。但是,如果没有生命周期问题,请说如果它返回了对count
的引用,那么从a
到b
的强加评估中仍然不会有UB。
答案 1 :(得分:15)
这是另一种使用std::initializer_list
来强制执行评估顺序的方法,该顺序具有从左到右的评估顺序:
#include <numeric> // for accumulate
#include <initializer_list>
template <class T>
auto diff(std::initializer_list<T> args)
{
return std::accumulate(args.begin(), args.end(), T(0), std::minus<>{});
}
const auto result = diff({increment(), increment()});
这会将您限制为相同类型的对象,并且需要键入其他大括号。