【问题标题】:Variadic templates, compiler apologies可变参数模板,编译器道歉
【发布时间】:2011-10-10 20:41:35
【问题描述】:

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

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

【问题讨论】:

  • 请不要告诉我使用sizeof...(args)
  • +1: "编译器道歉"...不是每天都看到。
  • 等等,为什么第二个版本是“诡计”?第一个版本同样使用部分特化。并且可以说第二个版本更干净、更强大,所以我一开始就不会考虑第一个版本。
  • 第一个版本不能接受 0 个参数(并且报告的参数比它应该的少 1 个)。
  • @Mr.Anubis:“请不要告诉我使用 sizeof...(args)” 为什么不呢?这就是你应该如何获得参数计数。

标签: c++ c++11 variadic-templates


【解决方案1】:

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

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

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

(最后,由于对 C++11 功能的支持被 GCC 标记为“实验性”,你真的不能对什么可行,什么不可行有任何期望,更不用说 为什么如何。这类问题只能由 GCC 开发人员在他们的邮件列表中合理地回答,而不是我们。我们不是读心术的人。)

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 为什么第二个版本没有遇到错误?这是我想知道的
    • @Mr.Anubis:这个漏洞非常狭窄。开发人员尝试过的 100% 的测试用例都没有遇到错误,否则他们会在您看到它之前将其修复。遇到错误是一种罕见的事件,避免错误是非常普遍的。哪些代码遇到了错误,或者没有告诉你任何关于代码的信息,只告诉你关于错误的信息。这里没有什么有趣的东西,除非您尝试修复错误,或者将崩溃报告归咎于现已修复的错误。
    猜你喜欢
    • 1970-01-01
    • 2019-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-10
    • 1970-01-01
    相关资源
    最近更新 更多