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

Declare member variables from variadic template parameter

本文关键字:声明 成员 变量 参数 variadic      更新时间:2023-10-16

显然,下面的代码不会在C 中编译。但是我有一个基于模板参数的零或多个数据项的类参数化类别的类别。

有什么办法可以声明一个类,该类别依赖于variadic模板参数的类,以便我可以访问每个类别?或其他一些方法来实现我想要的东西?

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

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;
}

您可以使用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;
}

在这里尝试

这是std::tuple的目的:

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

标准已覆盖您。只需声明std::tuple<Types...> items即可。

我希望能够使用具有折叠表达式的成员。所以我最终得到了:

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] + ...); });
    }
};