c – Variadic模板,编译器道歉

之前我曾问过类似的问题,明白我可以通过部分专业化来实现它.但是为了理解可变参数模板的基础知识我修改了这样的代码.

template<typename T, typename... args>
struct counter{
static const int value= 1+ counter<args...>::value;
};

template<typename T>
struct counter<T>{
static const int value = 0;
};

错误:“抱歉,未实现:无法将’args …’扩展为固定长度的参数列表”

我知道这是错误,并已在gcc 4.7.0中修复

所以要解决这一切,我们必须使用技巧或其他,这是部分专门模板.

template<typename... Args> struct counter;

template<>
struct counter<> {
static const int value = 0;
};

template<typename T, typename... Args>
struct counter<T, Args...> {
static const int value = 1 + counter<Args...>::value;
};

实际问题:所以我真的想知道部分特化在这里做了什么特殊效果,以便代码可以工作,或者我应该问部分特化如何解决问题? (为什么第二个版本没有碰到这个bug?).任何有动机问题和例子的解释都会非常有帮助.

最佳答案 第二个版本避免了这个错误,因为主模板被声明为模板< typename …>,即它是可变参数.错误的关键在于错误消息:“抱歉,未实现:无法将’args …’扩展为固定长度的参数列表”(强调我的).

因此,计数器< Args …> :: value将适用于第二种情况,因为计数器被定制为接受任意数量的参数.但是,在主模板声明为模板< typename T,typename … args>的第一种情况下,编译器必须将args分成固定长度部分(T)和可变参数部分(新args).据推测,这是您的GCC版本中未实现的功能.

我没有理由相信无论什么机器允许< T,Args …>第二种情况的专门化以匹配< typename …>主模板可以重复用于固定长度扩展.

(最后,由于CCC特征的支持被GCC标记为“实验性”,你真的不能期望什么会起作用,什么不起作用,更不用说为什么和如何.这些问题只能合理地GCC开发人员在他们的邮件列表中回答,而不是我们.我们不介意读者.)

点赞