如何在模板中使用嵌套的typedef?

时间:2015-03-12 16:14:55

标签: c++ templates

我想从模板化类型Test派生一个Base类型,我专门研究派生类型(即Base<Test>)。

在模板化类型中,我想使用派生类型(模板参数)中定义的typedef。

但是,我得到了这个编译错误:

error C2039: 'X' : is not a member of 'Test'

以下是代码段:

template <typename T>
class Base
{
protected:
  void func(typename T::X x) {}
};


class Test : public Base<Test>
{
public:
  typedef int X;
};

这是否可行,如果是,我需要做出什么修复?

(我看到了这类问题的几个答案,但看起来我的方案并没有通过前缀typename来修复 - 它是否与从派生类型专用的模板派生有关?)

4 个答案:

答案 0 :(得分:5)

除了typedef之外,您还可以将类型声明为基类中的第二个模板参数:

template <typename T, typename X>
class Base
{
protected:
  void func(X x) {}
};


class Test : public Base<Test, int>
{
public:
//  typedef int X;
};

答案 1 :(得分:2)

您的循环无法通过前向声明解决。但这会起作用,虽然(我怀疑)并没有你想要的那么强烈的定义。

template <typename T>
class Base
{
protected:
    template<typename Y>
    void func(Y x) {}
};

class Test : public Base<Test>
{
public:
    typedef int X;
};

如果func是公开的,那么您可以编写

Test t;
Test::X x;
t.func(x)

对于任何使用我想到的奇怪重复模板模式都是令人满意的。

答案 2 :(得分:1)

我不确定这种行为,也许有人可以澄清一下。但据我所知,当你做: public Base<Test>时,类型名称X不存在(因为在下面声明)。

如果在进行继承之前创建了一个包装类,则在执行继承时类型将存在,并且模板实例化将起作用。

使用VC ++ 2013编译

template <typename T>
class Base
{
protected:
    void func(typename T::X x) {}
};


class TestWrapper
{
public:
    typedef int X; //Declared, now it exists for the compiler
};

class Test
    :public Base<TestWrapper> //Compiles correctly
{

};

答案 3 :(得分:1)

这对我有用:

template <typename T> struct Traits;

template <typename Derived>
class Base
{
   protected:
      void func(typename Traits<Derived>::X x) {}
};


class Test;

template <> struct Traits<Test>
{
  typedef int X;
};


class Test : public Base<Test>
{
};