Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在模板中使用嵌套的typedef?_C++_Templates - Fatal编程技术网

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

C++ 如何在模板中使用嵌套的typedef?,c++,templates,C++,Templates,我想从我专门研究派生类型(即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 : publ

我想从我专门研究派生类型(即
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;
};
模板
阶级基础
{
受保护的:
void func(类型名T::X X){}
};
类测试:公共基
{
公众:
typedef int X;
};
这可行吗?如果可行,我需要做什么修正


(我看到了这类问题的一些答案,但似乎我的场景并没有通过在typename前面加前缀来修复-这与从专门使用派生类型的模板派生有关吗?

我不确定这种行为,也许有人可以澄清一下。但正如我所理解的那样,当您执行
:public Base
时,类型名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
{

};
模板
阶级基础
{
受保护的:
void func(类型名T::X X){}
};
类测试包装器
{
公众:
typedef int X;//声明,现在它对于编译器是存在的
};
课堂测试
:public Base//编译正确
{
};

您有一个不能用正向声明解决的循环。但这会起作用,尽管(我怀疑)并没有像你所希望的那样强烈地定义

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

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

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

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

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


class Test : public Base<Test, int>
{
public:
//  typedef int X;
};
模板
阶级基础
{
受保护的:
void func(X){}
};
类测试:公共基
{
公众:
//typedef int X;
};
这对我很有用:

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>
{
};
模板结构特征;
模板
阶级基础
{
受保护的:
void func(typename Traits::X X){}
};
课堂测试;
模板结构特征
{
typedef int X;
};
类测试:公共基
{
};

我喜欢这样。加一,欢迎使用Stack Overflow。虽然它不是最纯粹的CRTP。这适用于我上面的示例演示代码,但我不认为它适用于我试图编译的更复杂的实际代码:)我认为这就是你应该如何做这类事情-我想这有点像提取接口以避免两种类型之间的循环引用。
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>
{
};