C++ 函数默认模板参数能否放在非默认模板参数之前?

C++ 函数默认模板参数能否放在非默认模板参数之前?,c++,templates,c++11,C++,Templates,C++11,以下代码在gcc-4.7.1上编译: struct X {}; template <class T = X, typename U> void f(const U& m) { } int main() { f<>(0); } 所以我的问题是:在函数模板中将默认参数放在非默认参数之前是否正确?如果是,为什么第二个不编译?如果没有,为什么第一个要编译?C++11标准如何描述这种语法?类和别名明确禁止使用这种语法。n3290§14.1.11规定: 如果类

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

struct X {};

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


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

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

类和别名明确禁止使用这种语法。n3290§14.1.11规定:

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

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

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

但很明显,这与本案无关

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

A似乎证实了这一意图。该节最初提议的措辞是:

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


不过,我看不出那张便条在最终版本中的位置。

@Andrew,你发的帖子太长了。你能指出哪个答案说明将默认参数放在非默认参数之前是否正确吗?@icando:标准中没有任何内容禁止将函数模板的默认模板参数放在任何地方。只有类模板是受限制的。@KerrekSB,所以代码不被接受只是一个gcc错误?@KerrekSB-我刚刚得出了相同的结论。有趣的是,我的机器上的clang3.0在gcc拒绝的情况下出现故障。我认为这是允许的。如果不是故意的,那就是标准中的一个缺陷,没有拒绝它的措辞。虽然我的系统在编译它时也会出错,所以无论是哪种方式,现在编译器都会遇到问题!MacPorts中的clang-3.2实际上编译了它。那么也许叮当已经解决了?
struct X {};

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


int main() {
    f<>(0);
}
c.cpp: In function 'void f(const U&)':
c.cpp:5:15: error: no default argument for 'U'