c ++(g ++ - 4.x)模板问题

时间:2011-05-29 22:37:22

标签: c++ templates g++

我有这个简单的代码:

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

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

它在最近的g ++版本中运行良好,但是,在4.4或4.5中,我收到此错误:

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>'

我做错了什么?

2 个答案:

答案 0 :(得分:12)

这是因为在类Test<Writer>的正文中,在不提供模板参数的情况下命名Test会自动采用相同的参数(例如Writer)。

例如,这允许您将复制构造函数编写为:

Test(const Test&);

而不是

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

您可以通过使用其名称空间限定Test来解决此问题,例如

 typedef TestHelper< ::Test >  Helper;

注意:正如Tomalek建议的那样,原始用法在C ++ 0x中有效。以下是标准(强调我的)的相关段落,来自第14.6.1节([temp.local]):

  

与普通(非模板)类一样,类模板具有注入类名(第9节)。 inject-class-name可以用作模板名称类型名称使用时使用 template-argument-list 作为模板的模板参数 template-parameter ,或作为朋友类模板声明的 elaborated-type-specifier 中的最终标识符,它指的是类模板本身。否则,它等同于 template-name ,后跟&lt;&gt;中包含的类模板的 template-parameters

答案 1 :(得分:1)

@Ben可能是正确的,但这是一种完全不同的方式来编译它,不使用模板作为模板的args。

template<class Generator> // changed this to a simpler template
class TestHelper {};

template<class Writer>
class Test
{
            typedef TestHelper< typename Test :: Writer >  Helper; // 2nd change
};

我做了两处修改。 @Hugo,也许这就是你想要的,也许这就是旧版本的g ++所做的?

编译代码很容易,但这并不意味着它会按照你的想法做到!