我试图了解变体是如何实现的,并阅读:
http://www.codeproject.com/KB/cpp/TTLTyplist.aspx
而且我的印象是我无法编写采用 X 类型的变体;但是模板编写者选择了一些 N,而我在一个变体中只能有少于 N 个类型。
它是否正确?
谢谢!
我试图了解变体是如何实现的,并阅读:
http://www.codeproject.com/KB/cpp/TTLTyplist.aspx
而且我的印象是我无法编写采用 X 类型的变体;但是模板编写者选择了一些 N,而我在一个变体中只能有少于 N 个类型。
它是否正确?
谢谢!
在 C++03 中,没有可变参数模板。这意味着是;你只需要选择一些 N 就可以了,并接受它。
在 C++0x 中,会有可变参数模板,因此您可以对所有 X 使用一个定义。
如果您希望轻松更改数字,可以使用Boost.Preprocessor并让它为您完成工作:
#define MAXIMUM_TYPELIST_SIZE 20 // or something
struct empty{};
template <BOOST_PP_ENUM_BINARY_PARAMS(MAXIMUM_TYPELIST_SIZE, typename T, =empty)>
struct typelist;
template <BOOST_PP_ENUM_PARAMS(MAXIMUM_TYPELIST_SIZE, typename T)>
struct typelist
{
typedef T1 head;
typedef typelist<
BOOST_PP_ENUM_PARAMS(BOOST_PP_DEC(MAXIMUM_TYPELIST_SIZE), T)> tail;
enum
{
length = tail::length+1
};
};
如果MAXIMUM_TYPELIST_SIZE
是 5,这些宏将扩展到文章的内容。
(当然,如果您使用的是 Boost,只需使用他们的元编程库。)
是的——库的实现设置了一些限制。IIRC,在 Loki 中,默认情况下最大值为 99。看了那篇文章,他将限制设置为 5,这对于很多工作来说可能已经足够了,但我可以看到超过它的可能性;我无法完全想象超过 99 Loki 允许的值(尽管在任何一种情况下,如果你愿意,扩展限制都是一项微不足道的编辑工作)。
如果没有可变参数模板支持,模板作者只能提供看起来像可变参数模板的解决方法:
template<class Arg1=nil, class Arg2=nil /* , ... */>
struct foo {};
这里作者提供的模板参数的数量是限制。
如果他们不提供这样的解决方法,您将不得不求助于显式类型列表,相比之下,这非常笨拙:
typedef list<T1, list<T2, list<T3, nil> > > myTypeList;
foo<myTypeList>::bar;
这些不限于固定数量的类型,但不是我想明确使用的东西。
使用下一个 C++ 标准,这将使用真正的可变参数模板来解决:
template<class... Args> // can take 0..n arguments
struct foo {};
在现行标准下是正确的;模板只能有固定数量的参数,并且库使用诸如预处理器元编程之类的技术来模拟可变参数模板参数,直至达到一定的最大值。通常这在实践中并不是什么大问题,因为最大值被设置为远高于大多数人使用的值。
在新的 0x 标准中,支持真正的可变参数模板参数。