10

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?

BЈовић
  • 62,405
  • 41
  • 173
  • 273
Kan Li
  • 8,557
  • 8
  • 53
  • 93
  • http://stackoverflow.com/questions/2447458/default-template-arguments-for-function-templates – Andrew Jul 27 '12 at 09:25
  • @Andrew, the post you gave is too long. Can you point out which answer says about if it is correct to put default parameter before non-default ones? – Kan Li Jul 27 '12 at 09:31
  • 1
    @icando: There's nothing in the standard that *forbids* putting default template arguments for function templates anywhere. Only *class* templates are restricted. – Kerrek SB Jul 27 '12 at 09:43
  • 1
    @KerrekSB, so it is just a gcc bug that the code is not accepted? – Kan Li Jul 27 '12 at 09:47
  • @KerrekSB - I'd just arrived at the same conclusion. Interestingly clang3 .0 on my machine segfaults with the case that gcc rejects. – Flexo Jul 27 '12 at 09:47

1 Answers1

11

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.

Flexo
  • 87,323
  • 22
  • 191
  • 272
  • I *think* it's allowed. If wasn't meant to be it's a defect in the standard that there is no wording rejecting it. clang on my system segfaults compiling it though too, so it's certainly problematic for compilers at the moment either way! – Flexo Jul 27 '12 at 09:51
  • 1
    the clang-3.2 in my MacPorts actually compiles it. So maybe clang fixed that already? – Kan Li Jul 27 '12 at 09:55