传递std :: array作为模板变量函数的参数 [英] Passing std::array as arguments of template variadic function

查看:621
本文介绍了传递std :: array作为模板变量函数的参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想学习C ++ 11中的可变参数模板。我有一个类,它基本上是一个 std :: array 。我想能够将函数对象(理想地lambdas)传递给成员函数,然后将 std :: array 的元素作为函数对象的参数传递。

I am trying to learn about variadic templates in C++11. I have a class which is basically a wrapper around a std::array. I want to be able to pass function objects (ideally lambdas) to a member function and then have the elements of the std::array passed on as parameters of the function object.

我使用了一个 static_assert 来检查参数的数量是否与数组的长度相匹配,但我不能

I have used a static_assert to check that the number of parameters matches the length of the array but I cannot think of a way to pass the elements as arguments.

以下是代码

#include <iostream>
#include <array>
#include <memory>
#include <initializer_list>

using namespace std;

template<int N, typename T>
struct Container {
    template<typename... Ts>
    Container(Ts&&... vs) : data{{std::forward<Ts>(vs)...}} {
        static_assert(sizeof...(Ts)==N,"Not enough args supplied!");
    }

    template< typename... Ts>
    void doOperation( std::function<void(Ts...)>&& func )
    {
        static_assert(sizeof...(Ts)==N,"Size of variadic template args does not match array length");

        // how can one call func with the entries
        // of data as the parameters (in a way generic with N)
    }

    std::array<T,N> data;
};

int main(void)
{
    Container<3,int> cont(1,2,3);

    double sum = 0.0;
    auto func = [&sum](int x, int y, int z)->void{
        sum += x;
        sum += y;
        sum += z;
    };

    cont.doOperation(std::function<void(int,int,int)>(func));

    cout << sum << endl;

    return 0;
}



因此我的问题(如代码中所示)将数据的条目以通用 N func c $ c>?

So my question (as indicated in the code) is how can one pass the entries of data onto the function func in a way which is generic with N?

奖金问题:可以取消不方便地转换为 std ::

Bonus Question: Is it possible to do away with the unsightly conversion to std::function in main and pass in a lambda directly?

推荐答案

鉴于众所周知的索引基础设施:

Given the well-known indices infrastructure:

namespace detail
{
    template<int... Is>
    struct seq { };

    template<int N, int... Is>
    struct gen_seq : gen_seq<N - 1, N - 1, Is...> { };

    template<int... Is>
    struct gen_seq<0, Is...> : seq<Is...> { };
}

您可以通过这种方式重新定义类模板:

You could redefine your class template this way:

template<int N, typename T>
struct Container {
    template<typename... Ts>
    Container(Ts&&... vs) : data{{std::forward<Ts>(vs)...}} {
        static_assert(sizeof...(Ts)==N,"Not enough args supplied!");
    }

    template<typename F>
    void doOperation(F&& func)
    {
        doOperation(std::forward<F>(func), detail::gen_seq<N>());
    }

    template<typename F, int... Is>
    void doOperation(F&& func, detail::seq<Is...>)
    {
        (std::forward<F>(func))(data[Is]...);
    }

    std::array<T,N> data;
};

这是一个 生活示例

注意,您不需要构造 std :: function 中的对象main() std :: function 可以从lambda隐式构造。但是,你甚至不需要使用 std :: function ,这可能会导致不必要的运行时间开销。

Notice, that you do not need to construct an std::function object in main(): the std::function can be implicitly constructed from the lambda. However, you do not even need to use std::function at all here, possibly incurring in an unnecessary run-time overhead.

在上面的解决方案中,我只是让可调用对象的类型是一个模板参数,可以由编译器推导出来。

In the solution above, I just let the type of the callable object to be a template parameter that can be deduced by the compiler.

这篇关于传递std :: array作为模板变量函数的参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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