我正在尝试了解变体的实现方式,并阅读:
http://www.codeproject.com/KB/cpp/TTLTyplist.aspx
我得到的印象是我不能写一个采用X类型的变体;但模板编写者选择了一些N,而且我只能在一个变体中使用少于N个类型。
这是对的吗?
谢谢!
答案 0 :(得分:4)
在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,请使用他们的meta-programming library。)
答案 1 :(得分:2)
是的 - 库的实施设置了一些限制。 IIRC,在Loki,默认最大值为99。看了那篇文章,他把限制设定为5,这可能足以完成很多工作,但我可以看到超过它的可能性;我无法想象超过99 Loki允许(尽管在任何一种情况下,如果你想要扩展限制,这是一个微不足道的编辑工作。)
答案 2 :(得分:2)
如果没有可变参数模板支持,模板作者只能提供看起来像可变参数模板的变通方法:
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 {};
答案 3 :(得分:1)
根据现行标准,这是正确的;模板只能有固定数量的参数,并且库使用预处理器元编程等技术来模拟可变参数模板参数,最多可达一定的设置。通常情况下,这在实践中并不是一个大问题,因为最大值被设置为远高于大多数人使用的值。
在新的0x标准中,支持真正的可变参数模板参数。