【发布时间】:2010-12-31 15:58:43
【问题描述】:
在 GCC 上使用 C++11 进行可变参数模板编程时,偶尔会收到一条错误消息,提示“抱歉,未实现:无法将 '标识符...' 扩展为固定长度的参数列表。”如果我删除代码中的“...”,则会收到另一个错误:“错误:参数包未使用 '...' 展开”。
因此,如果我输入了“...”,则 GCC 称其为错误,如果我删除“...”,则 GCC 也称其为错误。
我能够处理这个问题的唯一方法是使用不同的方法从头开始完全重写模板元程序,并且(幸运的是)我最终想出了不会导致错误的代码。但我真的很想知道我做错了什么。尽管谷歌搜索并进行了大量实验,但我无法确定我在产生此错误的可变参数模板代码和没有错误的代码之间所做的不同。
错误消息的措辞似乎暗示代码应该按照 C++11 标准工作,但 GCC 还不支持它。或者它可能是一个编译器错误?
这是一些产生错误的代码。注意:我不需要您为我编写正确的实现,而只是指出导致此特定错误的代码是什么
// Used as a container for a set of types.
template <typename... Types> struct TypePack
{
// Given a TypePack<T1, T2, T3> and T=T4, returns TypePack<T1, T2, T3, T4>
template <typename T>
struct Add
{
typedef TypePack<Types..., T> type;
};
};
// Takes the set (First, Others...) and, while N > 0, adds (First) to TPack.
// TPack is a TypePack containing between 0 and N-1 types.
template <int N, typename TPack, typename First, typename... Others>
struct TypePackFirstN
{
// sorry, unimplemented: cannot expand ‘Others ...’ into a fixed-length argument list
typedef typename TypePackFirstN<N-1, typename TPack::template Add<First>::type, Others...>::type type;
};
// The stop condition for TypePackFirstN: when N is 0, return the TypePack that has been built up.
template <typename TPack, typename... Others>
struct TypePackFirstN<0, TPack, Others...> //sorry, unimplemented: cannot expand ‘Others ...’ into a fixed-length argument list
{
typedef TPack type;
};
编辑:我注意到虽然看起来像的部分模板实例化确实会导致错误:
template <typename... T>
struct SomeStruct<1, 2, 3, T...> {};
重写它不会产生错误:
template <typename... T>
struct SomeStruct<1, 2, 3, TypePack<T...>> {};
似乎您可以声明部分特化的参数是可变参数的;即这条线没问题:
template <typename... T>
但是你实际上不能使用专门化中的那些参数包,即这部分不行:
SomeStruct<1, 2, 3, T...>
事实上,如果你将包包装成其他类型,你就可以让它工作,例如:
SomeStruct<1, 2, 3, TypePack<T...>>
对我来说意味着对部分模板特化的可变参数的声明是成功的,你只是不能直接使用它。谁能证实这一点?
【问题讨论】:
-
现在可以使用
clang 3.2
标签: c++ templates g++ metaprogramming c++11