【问题标题】:Can function default template parameter be put before non-default ones?函数默认模板参数可以放在非默认参数之前吗?
【发布时间】:2012-07-25 23:07:53
【问题描述】:

以下代码在 gcc-4.7.1 上编译:

struct X {};

template <class T = X, typename U>
void f(const U& m) {
}


int main() {
    f<>(0);
}

但是,这个没有:

struct X {};

template <class T = X, typename U>
void f(const U& m) {
    auto g = [] () {};
}


int main() {
    f<>(0);
}

gcc-4.7.1 抱怨:

c.cpp: In function 'void f(const U&)':
c.cpp:5:15: error: no default argument for 'U'

所以我的问题是:在函数模板中将默认参数放在非默认参数之前是否正确?如果是,为什么第二个不编译?如果不是,为什么第一个编译? C++11 标准对这种语法有什么看法?

【问题讨论】:

  • @Andrew,你发的帖子太长了。您能否指出哪个答案表明将默认参数放在非默认参数之前是否正确?
  • @icando:标准中没有任何内容禁止将函数模板的默认模板参数放在任何地方。只有 class 模板受到限制。
  • @KerrekSB,所以代码不被接受只是gcc bug?
  • @KerrekSB - 我刚刚得出了同样的结论。有趣的是,我的机器上的 clang3 .0 在 gcc 拒绝的情况下出现了段错误。

标签: c++ templates c++11


【解决方案1】:

明确禁止类和别名。 n3290 § 14.1.11 规定:

如果类模板或别名模板的模板参数具有默认模板参数,则每个后续 模板参数应提供默认模板参数或模板参数 打包

对于函数,唯一的限制似乎与参数包有关:

函数模板的模板参数包不应 后跟另一个模板参数,除非该模板参数可以推导出来或具有默认值 论据

但显然这与本案无关。

鉴于 § 14 中没有任何内容禁止它用于功能,我们似乎不得不假设它是允许的。

note from a working group reports 似乎证实了这就是意图。该部分的原提议措辞是:

如果类模板的模板参数具有默认模板参数,则所有后续模板参数都应提供默认模板参数。 [注意:这不是函数模板的要求,因为模板参数可能会被推导出来(14.8.2 [temp.deduct])。]

不过,我看不到该注释在最终版本中的位置。

【讨论】:

  • 认为这是允许的。如果不是故意的,这是标准中的一个缺陷,没有拒绝它的措辞。虽然我的系统段错误也在编译它,所以无论哪种方式,这对编译器来说肯定是有问题的!
  • 我的 MacPorts 中的 clang-3.2 实际上会编译它。所以也许 clang 已经解决了这个问题?
猜你喜欢
  • 2012-06-01
  • 1970-01-01
  • 2015-05-19
  • 2017-11-13
  • 1970-01-01
  • 2019-12-14
  • 2013-02-28
  • 1970-01-01
相关资源
最近更新 更多