std::apply 是否为评估顺序提供保证?

Does std::apply provide a guarantee for order of evaluation?

在 c++ 中,未指定作为函数调用参数提供的表达式的求值顺序。 当我使用 std::apply 时,是否可以保证在元组的元素上按顺序调用该函数? 我有一个情况,重要的是函数首先应用于元组的第一个元素,然后是第二个,然后是第三个,....

作为反例:

template <class Tuple, size_t... Is>
void function(Tuple t, std::index_sequence<Is...>) {
    some_func( my_func(get<Is>(t))... );
}

不保证对元组的每个元素调用 my_func 的顺序。

I have a case where it matters that the function is first applied to the first element of the tuple, then the second, then the third, ....

那么你使用了错误的功能,因为 std::apply 做了一些与你想要的完全无关的事情。例如,

std::apply(f, std::make_tuple(1, 2))

returns

f(1, 2)

而不是尝试分别调用 f(1)f(2)

我认为这应该可行:

using args_tuple_type = decltype( std::make_tuple(my_func(get<Is>(t))...) );
std::apply(some_func, args_tuple_type{ my_func(get<Is>(t))... });

因为 my_func 调用都在花括号初始化器列表中,所以它们按顺序求值。 some_func 调用需要 std::apply,但排序保证并非来自 std::apply

不是因为元组不是聚合,它是通过构造函数调用构造的,构造函数参数通常不会按顺序求值。但是,如

中所述,使用大括号仍然可以进行排序
  • Are there sequence points in braced initializer lists when they apply to constructors?