【问题标题】:Empty parameter pack expansion different to manual empty parameter pack空参数包扩展不同于手动空参数包
【发布时间】:2015-11-04 12:02:52
【问题描述】:

似乎 GCC 将空参数包 A 扩展为另一个 参数包B 与手动输入空参数包不同 B。示例:

void baz();
void baz(int);

template<typename... Args, typename R>
void bar(R (*)(Args...));

template<typename... Args>
void foo()
{
    bar<Args...>(baz);
}

int main()
{
    foo<>();          // Deduces baz()
    //bar<>(baz);     // Ambiguous
    foo<int>();       // Deduces baz(int)
    bar<int>(baz);    // Deduces baz(int)
    //foo<void>();    // Ambiguous
    //bar<void>(baz); // Ambiguous
}

此行为标准是否符合?您可以看到herehere 区别的一个活生生的例子。

【问题讨论】:

  • f&lt;&gt; 不强制空包,只是告诉模板参数的前 0 个参数。
  • @Jarod42 这很有趣且违反直觉。您能在答案中详细说明吗?
  • 我想知道为什么template&lt;typename... Args, typename R&gt; 是正确的。不应该是template&lt; typename R, typename... Args&gt;吗?
  • @Glapa 是正确的。为什么不正确?
  • @Glapa:variadic 后面的参数应该是可扣除的(和R(*)(Args...))允许这样做。

标签: c++ language-lawyer variadic-templates


【解决方案1】:

f&lt;&gt; 不强制空包,只是告诉模板参数的前 0 个参数。

Clang 拒绝 foo&lt;&gt;() (Demo),因为它无法确定 bazbar&lt;&gt;(baz); 的哪个重载

gcc 接受它的事实似乎是一个错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多