4

我之前曾问过类似的问题,了解到我可以通过部分专业化使其工作。但是为了理解可变参数模板的基础知识,我修改了这样的代码。

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?)。任何有关动机问题和示例的解释都将非常有帮助。

4

2 回答 2

3

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

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

我没有理由相信任何允许将<T, Args...>第二种情况特化以匹配<typename...>主模板的机制都可以重用于固定长度扩展。

(Finally since the support of C++11 features is marked as 'experimental' by GCC you really can't have any expectation as to what will work and what won't, much less why and how. Those kind of questions can only reasonably be answered by GCC developers on their mailing-list, not us. We're not mind readers.)

于 2011-10-13T13:54:11.283 回答
-1

特殊的代码是第一种情况。它碰巧遇到了一个特定的编译器错误。

于 2011-10-10T21:54:23.110 回答