10

I have this code:

struct A{};

template<class T = A>
struct B {
    void foo() {}
};

B b; //Error: missing template arguments before 'b'
     //Error: expected ';' before 'b'
     //More errors
b.foo()

If I make foo() as a template function with the same template 'signature', the compiler doesn't complain about not specifying the template arguments:

struct A {};

struct B {
    template<class T = A>
    void foo() {}
};

B b; //OK
b.foo()

So why do I need to specify an argument for a template class with a default parameter, but not for a template function? Is there some subtlety I am missing?

The reason is because of template argument deduction failure for sure. But I want to know why.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
badmaash
  • 4,775
  • 7
  • 46
  • 61
  • Possible duplicate of *[Default template arguments for function templates](http://stackoverflow.com/questions/2447458/default-template-arguments-for-function-templates)*. – Peter Mortensen Jun 23 '15 at 21:33

3 Answers3

7

The correct syntax is this (demo):

B<> b; 

The default argument A is assumed for the class template B. The <> part tells the compiler that B is a class template and asks it to take the default parameter as the template argument to it.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • I see. But why does the template function work without this: `b.foo<>()`? – badmaash Jun 27 '12 at 17:07
  • My bad. Should have mentioned g++ 4.7.0 which has support for default template parameters for functions. So the code above definitely works. Try running with g++ 4.7.0. – badmaash Jun 27 '12 at 17:11
  • 2
    @Nawaz: [Yes it does](http://ideone.com/RvAcN); you need C++11 for the default argument, but the function call is fine. Function templates can be called without function argument lists; that allows overload resolution to consider both template specialisations and non-template overloads. – Mike Seymour Jun 27 '12 at 17:15
  • @MikeSeymour: Yup. I realized that C++03 doesn't allow default argument for function template. C++11 does, though. – Nawaz Jun 27 '12 at 17:16
  • Any reason why i don't need to do this: `b.foo<>()`? Is it because the deduction process is different in these two cases? – badmaash Jun 27 '12 at 17:25
  • @badmaash: As Mike said in his comment : `"Function templates can be called without function argument lists; that allows overload resolution to consider both template specialisations and non-template overloads."`. That makes perfect sense to me. – Nawaz Jun 27 '12 at 17:27
  • @badmaash: function templates are different from class templates. They just are. They obey different rules and can be used differently. – Kerrek SB Jun 27 '12 at 17:37
  • My comment would make more sense if I'd written "without *template* argument lists"; shame I can't correct that now. – Mike Seymour Jun 27 '12 at 18:26
1

The correct syntax, as Nawaz mentions already is:

B<> b;

The reason is that B is the template and B<> is the instantiation of the template with the default argument A. But you need the <> to differentiate when you want an instantiation.

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
0

Because you have to say that B is a template:

B<> b;

Even when you don't want to specify any of the arguments.

rodrigo
  • 94,151
  • 12
  • 143
  • 190