使用可变数量的elems创建POD

时间:2010-11-26 11:45:19

标签: templates c++11 variadic

我想要一个类型,这将是有效的POD,但我希望能够指定其中的方式和类型,例如:

template<Args...>
struct POD
{
//here I would like to create depending on Args appropriate types as a members.
};

是否可以使用C ++ 0x中的这个新的可变参数模板功能来实现它?

2 个答案:

答案 0 :(得分:0)

我从未使用过C ++ 0x可变参数模板功能,但以下代码在G ++ 4.5上编译:

template <typename... Args>
struct tuple;

template <typename T, typename... Args>
struct tuple<T, Args...> {
    T value;
    tuple<Args...> inner;
};

template <typename T>
struct tuple<T> {
    T value;
};

然而,初始化它们是......很奇怪,因为我们需要嵌套内部值:

int main() {
    tuple<int> n1 = { 23 };
    tuple<int, float> n2 = { 42, { 0.5f } };
    tuple<std::string, double, int> n3 = { "hello, world", { 3.14, { 97 } } };
}

检索这些值当然有点单调乏味。最简单的方法可能是提供get<N>()函数模板。

但我们无法直接实现get,因为函数模板不能部分专门化。要么我们需要使用SFINAE(读:boost::enable_if),要么我们需要将get的实际函数委托给可以部分专门化的类型。

在下面,我做了后者。但首先,我们需要另一个辅助类型特征:nth_type,它返回get函数的相应返回类型:

template <unsigned N, typename... Args>
struct nth_type;

template <unsigned N, typename T, typename... Args>
struct nth_type<N, T, Args...> : nth_type<N - 1, Args...> { };

template <typename T, typename... Args>
struct nth_type<0, T, Args...> {
    typedef T type;
};

易peasy。只需在类型列表中返回 n 类型。

现在我们可以编写get函数:

template <unsigned N, typename... Args>
inline typename nth_type<N, Args...>::type get(tuple<Args...>& tup) {
    return get_t<N, Args...>::value(tup);
}

就像我说的,这只是委托任务。没什么大不了的。实际上,我们可能希望为const元组设置另一个重载(但实际上我们会使用现有的tuple类型)。

现在为了杀人,然后是一份清淡的沙拉:

template <unsigned N, typename... Args>
struct get_t;

template <unsigned N, typename T, typename... Args>
struct get_t<N, T, Args...> {
    static typename nth_type<N, T, Args...>::type value(tuple<T, Args...>& tup) {
        return get_t<N - 1, Args...>::value(tup.inner);
    }
};

template <typename T, typename... Args>
struct get_t<0, T, Args...> {
    static T value(tuple<T, Args...>& tup) {
        return tup.value;
    }
};

就是这样。我们可以通过在先前定义的变量中打印一些值来测试它:

std::cout << get<0>(n1) << std::endl; // 23
std::cout << get<0>(n2) << std::endl; // 42
std::cout << get<0>(n3) << std::endl; // hello, world

std::cout << get<1>(n2) << std::endl; // 0.5
std::cout << get<1>(n3) << std::endl; // 3.14

std::cout << get<2>(n3) << std::endl; // 97

男人,这是有趣搞乱可变参数模板。

答案 1 :(得分:0)

您熟悉std::tuple吗?

AFAIK如果它的所有成员都是POD就是POD,如果我错了那么我猜它是不可能的。