假设我有一个大小为一种类型的模板类:
String
我想生成一个template<size_t N, typename T>
class C
{};
,它能够将这个类保存在多种大小和类型上,例如对于尺寸boost::variant
和1
以及类型2
和int
,它将是
unsigned int
问题在于我需要在多个地方进行此设置,并且每次都需要不同的尺寸和类型。 是否有一些模板元编程魔法可以从可能值列表中生成这些变体,这些都是
typedef boost::variant<
C<1, int>,
C<1, unsigned int>,
C<2, int>,
C<2, unsigned int>
> my_variant;
答案 0 :(得分:4)
#include <boost/variant.hpp>
#include <tuple>
#include <iostream>
#include <typeinfo>
template<size_t N, typename T>
class C
{};
template<template <size_t, class> class T>
struct combine
{
template<size_t... Ns> struct sizes;
template<size_t N>
struct sizes<N>
{
template<typename... Types>
struct types
{
typedef std::tuple<T<N, Types>...> type;
};
};
template<size_t N, size_t... Ns>
struct sizes<N, Ns...>
{
template<typename... Types>
struct types
{
typedef typename sizes<N>::template types<Types...>::type head;
typedef typename sizes<Ns...>::template types<Types...>::type tail;
typedef decltype(std::tuple_cat<head, tail>(std::declval<head>(), std::declval<tail>())) type;
};
};
};
template<typename... Types>
auto to_variant(const std::tuple<Types...>&)
{
return boost::variant<Types...>();
}
struct typename_visitor : public boost::static_visitor<>
{
template<size_t N, typename T>
void operator()(const C<N, T>& c)
{
std::cout << "C<" << N << ", " << typeid(T).name() << ">\n";
}
};
int main()
{
combine<C>::sizes<1, 2>::types<int, unsigned int>::type v;
auto var = to_variant(v);
var = C<1, int>();
// var = C<3, int>(); // doesn't compile
// var = C<1, short>(); // doesn't compile
var.apply_visitor(typename_visitor()); // prints C<1, int>
}