C ++ (g ++ - 4.x) problem with templates

I have this simple code:

template<template <class> class Generator> class TestHelper {}; template<class Writer> class Test { typedef TestHelper< Test > Helper; }; 

It works fine on recent g ++ versions, but in 4.4 or 4.5 I get this error:

 test.cpp:7: error: type/value mismatch at argument 1 in template parameter list for 'template<template<class> class Generator> class TestHelper' test.cpp:7: error: expected a class template, got 'Test<Writer>' 

What am I doing wrong?

+8
c ++ templates g ++
source share
2 answers

This is because inside the body of the Test<Writer> class, naming Test without providing template arguments automatically takes the same arguments (e.g., Writer ).

For example, this allows you to write a copy constructor as:

 Test(const Test&); 

instead

 Test::Test(const Test<Writer>&); 

You can overcome this by assigning Test your namespace, for example

  typedef TestHelper< ::Test > Helper; 

NOTE. As Tomalek suggests, the original use is valid in C ++ 0x. Here is the relevant section of the standard (shock), from section 14.6.1 ( [temp.local] ):

Like regular (non-template) classes, class templates have a name with the class introduced (section 9). The name of the entered class can be used as a template name or type name. When used with a list -argument-template , as a template argument for a template-template or as a final identifier in a specified qualifier of the type declaration template, the class of friends refers to the class template itself . Otherwise, this is equivalent to the template name, followed by the template parameters of the class template enclosed in <>.

+12
source share

@Ben is probably right, but here's a completely different way to get it to compile, which doesn't use patterns as arguments for patterns.

 template<class Generator> // changed this to a simpler template class TestHelper {}; template<class Writer> class Test { typedef TestHelper< typename Test :: Writer > Helper; // 2nd change }; 

I made two changes. @Hugo, maybe this is what you wanted, and maybe this is what older versions of g ++ did?

It's easy to get the code to compile, but that doesn't mean that it does what you think it does!

+1
source share

All Articles