Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can function default template parameter be put before non-default ones?

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?

like image 447
Kan Li Avatar asked Jul 27 '12 09:07

Kan Li


People also ask

Can template parameters have default values?

You can give default values to template parameters for class templates (but not function templates). template <class Elem = int> class Array; template <unsigned Size = 100> class String; If a template parameter has a default value, all parameters after it must also have default values.

CAN default arguments be used with the template?

You cannot give default arguments to the same template parameters in different declarations in the same scope. The compiler will not allow the following example: template<class T = char> class X; template<class T = char> class X { };

Which parameter is legal for non-type template?

Which parameter is legal for non-type template? Explanation: The following are legal for non-type template parameters:integral or enumeration type, Pointer to object or pointer to function, Reference to object or reference to function, Pointer to member.

What is the difference between the function template and template function?

"A function template is a template that is used to generate functions. A template function is a function that is produced by a template. For example, swap(T&, T&) is a function tem-plate, but the call swap(m, n) generates the actual template function that is invoked by the call."


1 Answers

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.

like image 99
Flexo Avatar answered Oct 03 '22 17:10

Flexo