Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

template method and default template argument

My problem can be resumed by the following piece of code:

template <typename T> struct C2;

template <typename T> 
struct C1
{
  template <typename Type,
        template <typename Ti> class Container = C2>
  void m() {}
};


template <typename T> 
struct C2
{
  template <typename Type = int,
        template <typename Ti> class Container = C2> // <-- Here is the problem!
  void m() {}

};

The gnu compiler, version 4.8.1 fails with the following message:

test-temp.C:16:47: error: invalid use of type ‘C2<T>’ as a default value for a template template-parameter
      template <typename Ti> class Container = C2> 

It refers to default template parameter C2 for the the method C2::m.

Apparently (it is my opinion), the compiler is seeing C2<T> as default parameter instead of C2 (without <T>). So, when it finds the instruction it fails because type C2<T> does not match with Container.

However, clang++, just for exactly the same code, compiles fine!

My questions:

  1. Which compiler has the truth?
  2. Is there some alternative for expressing the same sense with the current version of gnu compiler?

Thanks in advance

Leandro

like image 295
lrleon Avatar asked Sep 25 '13 19:09

lrleon


People also ask

How default arguments are used in template?

If one template parameter has a default argument, then all template parameters following it must also have default arguments. For example, the compiler will not allow the following: template<class T = char, class U, class V = int> class X { };

What is a template argument?

A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.

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

Function Template is the correct terminology (a template to instantiate functions from). Template Function is a colloquial synonym. So, there's no difference whatsoever.

Can we have default argument in fun template?

Like function default arguments, templates can also have default arguments.

What is the difference between typename and class in template?

There is no semantic difference between class and typename in a template-parameter. typename however is possible in another context when using templates - to hint at the compiler that you are referring to a dependent type. §14.6.


1 Answers

I think Clang is correct, and g++ is in error, quote from the draft Standard (bold emphasis is mine)

14.6.1 Locally declared names [temp.local]

1 Like normal (non-template) classes, class templates have an injected-class-name (Clause 9). The injectedclass-name can be used as a template-name or a type-name. When it is used with a template-argument-list, as a template-argument for a template template-parameter, or as the final identifier in the elaborated-typespecifier of a friend class template declaration, it refers to the class template itself. Otherwise, it is equivalent to the template-name followed by the template-parameters of the class template enclosed in <>.

You can use the :: scope resolution operator to beat g++ into submission

template <typename T> 
struct C2
{
  template <typename Type = int,
        template <typename Ti> class Container = ::C2> 
                                              // ^^ <-- here is the solution!
  void m() {}

};

Live Example.

like image 189
TemplateRex Avatar answered Sep 19 '22 20:09

TemplateRex