10

以下代码在 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 标准如何描述这种语法?

4

1 回答 1

11

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

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

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

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

但显然这与本案无关。

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

工作组报告的一份说明似乎证实了这就是意图。该部分的原始提议措辞是:

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

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

于 2012-07-27T09:27:19.507 回答