我了解当我调用诸如
a(b(),c());
那么就可以在<= C ++ 14中未定义其行为,而在> = C ++ 17中未指定其行为,这是由编译器确定是求值b还是c首先求值。
我想知道强制执行评估命令的最佳方法。我将编译为C ++ 14。
立即想到的是这样的事情:
#include <iostream>
int count = 5;
auto increment(){
    return count++;
}
template <typename A, typename B>
auto diff(A && a, B && b){
   return a - b;
}
int main() {
    auto && a = increment();
    auto && b = increment();
    auto c = diff(a,b);
}
我处于不确定的行为状态吗?或者这是如何“强制”执行评估命令的?
Sto*_*ica 27
分隔语句的分号强加了“在发生之前”的关系。
auto && a = increment()必须先评估。这是有保证的。a在第二次调用之前,返回的临时文件将绑定到引用(并延长其寿命)increment。
没有UB。这是在强制评估顺序的方式。
这里唯一的陷阱是,如果increment自身返回引用,那么您就需要担心生命周期问题。但是,如果没有生存期问题,例如说它返回了对的引用count,那么从施加的评估中a,仍然不会存在UB b。
lub*_*bgr 16
这是强制评估顺序的另一种方法,使用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()});
这将您限制为相同类型的对象,并且您需要键入其他大括号。