等价于元组的 std::transform

Equivalent of std::transform for tuples(等价于元组的 std::transform)
本文介绍了等价于元组的 std::transform的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要一个函数,其行为类似于元组的 std::transform.基本上要实现的功能是

I want a function that will behave like std::transform for tuples. Basically the functionality to be implemented is

template<size_t From, size_t To, class Tuple, class Func>
void tuple_transform(Tuple&& source, Tuple&& target, Func f)
{
    // elements <From, To> of `target` ti become `f(si)`, where
    // si is the corresponding element of `source`
};

我相信要实现这一点,我需要一个 编译时整数范围 结构,它是 std::index_sequence 的泛化,我已经实现了它这里 与 cti::range.我也相信这种类型的编译时间遍历在这里是理想的:

I believe that to implement this I'll need a compile time integer range struct, a generalization of std::index_sequence and I've implemented it here with cti::range. I also believe that this type of compile time traversal is ideal here :

template<class Func, class Tuple, size_t...Is>
void for_each_in_tuple(Func f, Tuple&& tuple, std::index_sequence<Is...>){
    using expander = int[];
    (void)expander { 0, ((void)f(std::get<Is>(std::forward<Tuple>(tuple))), 0)... };
}

template<class Func, class Tuple>
void for_each_in_tuple(Func f, Tuple&& tuple){
    for_each_in_tuple(f, std::forward<Tuple>(tuple),
               std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>::value>());
}

任何人都可以帮助我实施吗?

Can anyone help me with the implementation ?

@MohitJain 与链接的代码 (tuple_transform) 一样,没有考虑到这一点(Func 具有单一类型).如果这样解决,我可以通过传递模板模板参数 template<class> 轻松扩展它.class Func 并要求我的转换类型是这样的

@MohitJain Like in the code linked (tuple_transform) this is not taken into account (Func has a single type). If this is solved like that, I could easily extend it by passing a template template parameter template<class> class Func and mandate that my transformation types are like this

template<typename T>
struct Func
{
    static void apply(T& val) { ... }
}

然后在元组变换的主体内,每个变换函数可以这样调用:

then inside the body of tuple transform, each transformation func could be called like :

get<I>(target) = func<typename tuple_element<I, Tuple>::type>::apply(get<I>(source))

<小时>

编辑

刚刚在 accu 2015 上进行了一次闪电演讲.以上是演示结束时的 CodeKata.我将在 这里 留下演示文稿,希望它对任何实施都有帮助尝试(我认为几乎所有需要的工具都已提供,因此我们将对此进行更多尝试)


EDIT

Just gave a lightning talk @ accu 2015. The above was the CodeKata at the end of the presentation. I'll leave here the presentation, hopefullly it'll help with any implementation attempts (I think pretty much every tool required is presented, so we'll have more attempts at this)

推荐答案

这是一个使用 index_range 的解决方案模板整数范围">这里.

Here's a solution that uses index_range from here.

template<size_t SN, size_t DN, class TSrc, class TDest, class Func>
void tuple_call_assign(TSrc&& source, TDest& target, Func f)
{
    std::get<DN>(target) = f(std::get<SN>(std::forward<TSrc>(source))); 
}

template<size_t From, size_t To, class TSrc, class TDest, class Func, size_t...Is, size_t...DIs>
void tuple_transform(TSrc&& source, TDest& target, Func f,
                     std::index_sequence<Is...>, std::index_sequence<DIs...>)
{
    using expander = int[];
    (void)expander { 0, (tuple_call_assign<Is,DIs>(std::forward<TSrc>(source),target,f), 0)... };
}

template<size_t From, size_t To, size_t FromDest, class TSrc, class TDest, class Func>
void tuple_transform(TSrc&& source, TDest& target, Func f)
{
    static_assert(To > From, "Range must be increasing");
    static_assert(To <= std::tuple_size<std::decay_t<TSrc>>::value+1, 
        "Range must be valid for source tuple");
    constexpr size_t RangeSize = To-From;
    static_assert(FromDest+RangeSize <= std::tuple_size<std::decay_t<TDest>>::value, 
        "Range must be valid for target tuple");

    tuple_transform<From,To>(std::forward<TSrc>(source), target, f,
                    index_range<From,To>(), index_range<FromDest, FromDest+RangeSize>());
}

演示

这需要第三个模板参数来指定要转换为目标元组的起始索引.

This takes a third template argument to specify a starting index to transform into the target tuple.

这篇关于等价于元组的 std::transform的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Rising edge interrupt triggering multiple times on STM32 Nucleo(在STM32 Nucleo上多次触发上升沿中断)
How to use va_list correctly in a sequence of wrapper functions calls?(如何在一系列包装函数调用中正确使用 va_list?)
OpenGL Perspective Projection Clipping Polygon with Vertex Outside Frustum = Wrong texture mapping?(OpenGL透视投影裁剪多边形,顶点在视锥外=错误的纹理映射?)
How does one properly deserialize a byte array back into an object in C++?(如何正确地将字节数组反序列化回 C++ 中的对象?)
What free tiniest flash file system could you advice for embedded system?(您可以为嵌入式系统推荐什么免费的最小闪存文件系统?)
Volatile member variables vs. volatile object?(易失性成员变量与易失性对象?)