37

This is my code

#include <vector>
template <typename T, template<typename> class C = std::vector >
struct FooBar
{
   /*codez*/
};
template<typename T>
struct Global{};

int main()
{
   struct Local{};  
   FooBar<Local,Global> k;
}

This is the error that I get

template argument for ‘template<class T, template<class> class C> struct FooBar’ uses local type ‘main()::Local’

Which part of the standard says that this is wrong? I am using gcc 4.5.1. How can make this code work?

Ron Kanga
  • 453
  • 1
  • 4
  • 6

2 Answers2

33

Which part of the standard says that this is wrong?

That would be §14.3.1/2 from the 2003 C++ Standard:

A local type, a type with no linkage, an unnamed type or a type compounded from any of these types shall not be used as a template-argument for a template type-parameter.


How can make this code work?

Don't use a local type as a template argument.

Note that this restriction has been lifted in C++11, so using that language standard you are able to use a local type as a template argument.

Columbo
  • 60,038
  • 8
  • 155
  • 203
James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • I used `-std=c++0x` option and the code works. However if I use `FooBar k;` instead of `FooBar k;` I get some errors. What's wrong with `FooBar k`? – Ron Kanga Apr 22 '11 at 03:38
  • I'm glad to hear that g++ supports that feature. As for the problem with `FooBar`, it is because `std::vector` is not a valid template template argument for `template class` because `std::vector` isn't declared as `std::vector`, it's declared as `std::vector`. – James McNellis Apr 22 '11 at 03:39
  • @Ron: `std::vector` has _two_ template arguments. So, `template class C = std::vector> struct FooBar { .. };` See it working [here](http://www.ideone.com/9FQZP). – Lightness Races in Orbit Apr 22 '11 at 03:41
8

14.3.1/2

A local type, a type with no linkage, an unnamed type or a type compounded from any of these types shall not be used as a template-argument for a template type-parameter.

Try compiling your code with -std=c++0x option (gcc 4.5.1). C++0x lifts the restriction and so you can use a local type as template argument.

Prasoon Saurav
  • 91,295
  • 49
  • 239
  • 345