Reputation: 8797
The following piece of code does compile on gcc-4.7.1:
struct X {};
template <class T = X, typename U>
void f(const U& m) {
}
int main() {
f<>(0);
}
However, this one doesn't:
struct X {};
template <class T = X, typename U>
void f(const U& m) {
auto g = [] () {};
}
int main() {
f<>(0);
}
gcc-4.7.1 complains:
c.cpp: In function 'void f(const U&)':
c.cpp:5:15: error: no default argument for 'U'
So my question is: is putting default parameters before non-default parameters correct in function template? If yes, why doesn't the second one compile? If no, why does the first one compile? How does C++11 standard say about this syntax?
Upvotes: 10
Views: 898
Reputation: 88711
It is explicitly forbidden for classes and aliases. n3290 § 14.1.11 states:
If a template-parameter of a class template or alias template has a default template-argument, each subsequent template-parameter shall either have a default template-argument supplied or be a template parameter pack
For functions the only restriction seems to be related to parameter packs:
A template parameter pack of a function template shall not be followed by another template parameter unless that template parameter can be deduced or has a default argument
But clearly that doesn't concern this case.
Given that nothing in § 14 forbids it for functions it seems we have to assume it is permitted.
A note from a working group reports seems to confirm that this is the intention. The original proposed wording of that section is:
If a template-parameter of a class template has a default template-argument, all subsequent template-parameters shall have a default template-argument supplied. [Note: This is not a requirement for function templates because template arguments might be deduced (14.8.2 [temp.deduct]).]
I can't see where that note went in the final version though.
Upvotes: 11