可变参数模板,编译器抱歉

发布于 2024-12-09 00:48:51 字数 865 浏览 0 评论 0原文

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

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浮华 2024-12-16 00:48:51

第二个版本避免了该错误,因为主模板被声明为 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 because counter is tailored to accept any number of arguments. However, in the first case where the primary template is declared as template<typename T, typename... args>, the compiler has to separate args into a fixed-length part (T) and a variadic part (the new args). 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.)

杀お生予夺 2024-12-16 00:48:51

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

The code that's special is the first case. It happens to hit a particular compiler bug.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文