我想要一个类型,这将是有效的POD,但我希望能够指定其中的方式和类型,例如:
template<Args...>
struct POD
{
//here I would like to create depending on Args appropriate types as a members.
};
是否可以使用C ++ 0x中的这个新的可变参数模板功能来实现它?
答案 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,如果我错了那么我猜它是不可能的。