从variadic模板参数声明成员变量

时间:2016-11-24 08:36:40

标签: c++

显然,下面的代码不能用C ++编译。但我有一个案例,我想根据模板参数参数化一个包含零个或多个数据项的类。

有什么方法可以声明一个数据成员依赖于可变参数模板参数的类,所以我可以访问它们中的每一个?或其他一些方式来达到我想要的目的?

这是一个真实的程序,我已经解决了一个完全不同的方式,但现在我对如何做到这一点的更抽象的问题感兴趣。

template <typename... Types> class Data
{
    // Declare a variable of each type in the parameter pack
    // This is NOT valid C++ and won't compile...
    Types... items;
};

struct Item1
{
    int a;
};

struct Item2
{
    float x, y, z;
};

struct Item3
{
    std::string name;
}

int main()
{
    Data<Item1, Item2> data1;
    Data<Item3> data2;
}

4 个答案:

答案 0 :(得分:11)

您可以使用std::tuple

#include <tuple>

template <typename... Types> class Data
{
    std::tuple<Types...> items;
};

struct Item1
{
    int a;
};

struct Item2
{
    float x, y, z;
};

struct Item3
{
    std::string name;
};

int main()
{
    Data<Item1, Item2> data1;
    Data<Item3> data2;
}

试试here

答案 1 :(得分:9)

这是std::tuple的目的:

template <typename... Types> class Data
{
    std::tuple<Types...> items;
};

答案 2 :(得分:6)

该标准已经涵盖了你。只需声明std::tuple<Types...> items即可。

答案 3 :(得分:2)

我希望能够将成员与折叠表达式一起使用。所以我最后得到了:

template <class T, class... rest> class hold : hold<rest...> {
    using base = hold<rest...>;
    T v_;

public:
    hold(T v, rest... a) : base(a...), v_(v) {}

    template <class F, class... args> auto apply(F f, args... a) {
        return base::apply(f, a..., v_);
    }
};

template <class T> class hold<T> {
    T v_;

public:
    hold(T v) : v_(v) {}

    template <class F, class... args> auto apply(F f, args... a) {
        return f(a..., v_);
    }
};

这将有助于:

template <class scalar, class... arrays> struct plus_expr {
    hold<arrays...> a_;

    plus_expr(arrays... a) : a_(a...) {}

    scalar operator[](index const i) {
        return a_.apply([i](arrays... a) { return (a[i] + ...); });
    }
};