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?
在 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?