6

Take the following example:

#include <vector>

template <typename T, template <class T> class Container>
std::vector<T> To_Vector(Container<T> const& c){
  return std::vector<T>( c.begin(), c.end() );
}

int main(){}

With g++-5, it compiles without errors:

g++-5 -o main main.cpp 

With g++-6 is fails to compile:

g++-6 -o main main.cpp
main.cpp:4:33: error: declaration of template parameter ‘T’ shadows template parameter
 template <typename T, template <class T> class Container>
                                 ^~~~~
main.cpp:4:11: note: template parameter ‘T’ declared here
 template <typename T, template <class T> class Container>

Is the compiler wrong? Is my code wrong?
Why does g++-5 compile this code while g++-6 does not?


g++-5 --version    
g++-5 (Ubuntu 5.4.1-2ubuntu1~14.04) 5.4.1 20160904
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

g++-6 --version
g++-6 (Ubuntu 6.2.0-3ubuntu11~14.04) 6.2.0 20160901
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Trevor Hickey
  • 36,288
  • 32
  • 162
  • 271
  • @skypjack Ok, so I should leave out the 'T' in , because just builds for me. – Trevor Hickey Sep 07 '16 at 19:51
  • It's a valid and working solution. That `T` is useless in your example, isn't it? – skypjack Sep 07 '16 at 19:54
  • @skypjack You're right. I must have been confused in thinking that the container type name had to be specialized on type T, but that happens on the actual parameters. – Trevor Hickey Sep 07 '16 at 20:00
  • Yeah, exactly, the template parameter list of the function only mentions a template class having a parameter list with size 1. The name of the parameter is useless in this case. – skypjack Sep 07 '16 at 20:02

1 Answers1

4

The behaviour of g++6 is correct because according to the standard:

A template-parameter shall not be redeclared within its scope (including nested scopes). A template-parameter shall not have the same name as the template name.

The scope of T begins right after its declaration, so it extends into the following template template parameter, which redeclares T as a template parameter, therefore this rule is violated.

I imagine the change between g++5 and g++6 was due to fixing some bug report around a similar issue.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312