将功能应用于元组的每个元素 [英] Applying a function to each element of a tuple
问题描述
给出一个类似于 std :: tuple
的对象(即定义了 tuple_size
和 get
语义)和一元函子对象 ftor
,我希望能够调用 ftor
在类似 tuple
的对象的每个元素上。
Given an std::tuple
-like object (i.e. with defined tuple_size
and get
semantics) and a unary functor object ftor
, I want to be able to call ftor
on each element of the tuple
-like object.
如果我忽略返回值,我就会知道int数组技巧:
If I disregard the return value, I am aware of the int array trick:
namespace details {
template <typename Ftor, typename Tuple, size_t... Is>
void apply_unary(Ftor&& ftor, Tuple&& tuple, std::index_sequence<Is...>) {
using std::get;
int arr[] = { (ftor(get<Is>(std::forward<Tuple>(tuple))), void(), 0)... };
}
} // namespace details
template <typename Ftor, typename Tuple>
void apply_unary(Ftor&& ftor, Tuple&& tuple) {
details::apply_unary(std::forward<Ftor>(ftor),
std::forward<Tuple>(tuple),
std::make_index_sequence<std::tuple_size<Tuple>::value> {});
}
如果我想要返回值,可以替换 int []
技巧,而是调用 std :: make_tuple
并将其返回。只要对 ftor
对象的调用都不具有 void
返回值...
If I want the return values, I could replace the int []
trick with a call to std::make_tuple
instead and return that. That would work provided that none of the calls to the ftor
object have a void
return value...
因此,我的问题是:考虑到我想获得通话结果,如何处理可能返回 void $ c $的通话c>?
The question I have is therefore: considering I want to get the results of the call, how can I handle calls that might return void
?
唯一的要求是我应该将结果作为一个元组得到,并能够分辨出哪个调用导致了该结果元组的哪个元素。
The only requirement is that I should get the results as a tuple and be able to tell which call lead to which element of the said result tuple.
推荐答案
另一种方式:
namespace details {
struct apply_unary_helper_t {};
template<class T>
T&& operator,(T&& t, apply_unary_helper_t) { // Keep the non-void result.
return std::forward<T>(t);
}
template <typename Ftor, typename Tuple, size_t... Is>
void apply_unary(Ftor&& ftor, Tuple&& tuple, std::index_sequence<Is...>) {
auto r = {(ftor(std::get<Is>(std::forward<Tuple>(tuple))), apply_unary_helper_t{})...};
static_cast<void>(r); // Suppress unused variable warning.
}
} // namespace details
template <typename Ftor, typename Tuple>
void apply_unary(Ftor&& ftor, Tuple&& tuple) {
details::apply_unary(std::forward<Ftor>(ftor),
std::forward<Tuple>(tuple),
std::make_index_sequence<std::tuple_size<std::remove_reference_t<Tuple>>::value> {});
}
在上面,它适用于运算符,
到 ftor
和 apply_unary_helper_t
的结果。如果 ftor
的结果为 void
,则 r
为 std :: initializer_list<详细信息:: apply_unary_helper_t>
,否则 r
是 std :: initializer_list< ; decltype(ftor(...))>
,您可以利用。
In the above, it applies operator,
to the result of ftor
and apply_unary_helper_t
. If the result of ftor
is void
, then r
is std::initializer_list<details::apply_unary_helper_t>
, otherwise r
is std::initializer_list<decltype(ftor(...))>
which you can make use of.
这篇关于将功能应用于元组的每个元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!