将功能应用于元组的每个元素 [英] Applying a function to each element of a tuple

查看:76
本文介绍了将功能应用于元组的每个元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出一个类似于 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

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆