可变参数模板,编译器抱歉
我之前曾问过类似的问题,我知道我可以通过部分专业化来使其工作。但为了理解可变参数模板的基础知识,我修改了这样的代码。
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?)。任何关于动机问题和例子的解释都会非常有帮助。
I had asked the similar question before , understood that i can make it work by partially specialization. But to understand variadic templates basics i modified the code such like this.
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;
};
error : "sorry, unimplemented: cannot expand 'args ...' into a fixed-length argument list"
i understand this is bug and has been fixed in gcc 4.7.0
so to fix all this we have to use trick or whatever , which is partial specializing the template.
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;
};
Actual question: so I really want to know what special effect does partial specialization does here so that code works or I should ask how partial specialization resolves the issue? (why is it second version doesn't hits the bug? ). Any explanation with motivation problem and examples will be very helpful.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
第二个版本避免了该错误,因为主模板被声明为
template
,即它是可变参数。该错误的关键在于错误消息:“抱歉,未实现:无法将'args ...'扩展为固定长度参数列表”(强调我的)。因此
counter::value
将适用于第二种情况,因为counter
被定制为接受任意数量的参数。但是,在第一种情况下,主模板声明为template
,编译器必须将args
分离为 固定长度部分(T
)和可变参数部分(新的args
)。据推测,这正是您的 GCC 版本中未实现的功能。我没有理由相信任何机制都允许第二种情况的
专门化来匹配
> 主模板可重复用于定长扩展。(最后,由于 C++11 功能的支持被 GCC 标记为“实验性”,因此您真的不能对什么会起作用、什么不会有任何期望,更不用说为什么和< em>如何。这些问题只能由 GCC 开发人员在他们的邮件列表中合理地回答,我们不是读者。)
The second version avoids the bug because the primary template is declared as
template<typename...>
, i.e. it's variadic. The key to the bug is in the error message: "sorry, unimplemented: cannot expand 'args ...' into a fixed-length argument list" (emphasis mine).Thus
counter<Args...>::value
will work on that second case becausecounter
is tailored to accept any number of arguments. However, in the first case where the primary template is declared astemplate<typename T, typename... args>
, the compiler has to separateargs
into a fixed-length part (T
) and a variadic part (the newargs
). Presumably that's the very functionality that is not implemented in your version of GCC.I have no reason to believe that whatever machinery allows the
<T, Args...>
specialization of the second case to match the<typename...>
primary template could be reused for fixed-length expansion.(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.)
特殊的代码是第一种情况。它碰巧遇到了一个特定的编译器错误。
The code that's special is the first case. It happens to hit a particular compiler bug.