开发者

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

开发者 https://www.devze.com 2023-03-08 22:29 出处:网络
I have this simple code: template<template <class> class Generator> class TestHelper {}; template<class Writer开发者_开发技巧>

I have this simple code:

template<template <class> class Generator>
class TestHelper {};

template<class Writer开发者_开发技巧>
class Test
{
    typedef TestHelper< Test >  Helper;  
};

It's works great on last 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 I'm doing wrong?


It's because inside the body of class Test<Writer>, naming Test without providing the template arguments automatically assumes the same arguments (e.g. Writer).

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

Test(const Test&);

instead of

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

You can overcome this by qualifying Test with its namespace, e.g.

 typedef TestHelper< ::Test >  Helper;

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

Like normal (non-template) classes, class templates have an injected-class-name (Clause 9). The injected-class-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-type-specifier 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 <>.


@Ben is probably right, but here's a totally different way to get it to compile, that doesn't use templates as args to templates.

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 code to compile, but that doesn't mean that it does what you think it does!

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号