How to use a nested template in a template?

I want to get the Test type from the Base template type, which I specialize in a derived type (i.e. Base<Test> ).

Inside a templated type, I want to use the typedef defined in the derived type (template parameter).

However, I get this compilation error:

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

Here is the code snippet:

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

This is doable, and if so, what correction do I need to do?

(I see a couple of answers for this problem, but it looks like my script is not fixed with the typename prefix - is there something to do with getting a template specialized with a derived type?)

+6
source share
4 answers

This works for me:

 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> { }; 
+1
source

As an alternative to typedef, you can also declare type as the second argument to the template in the base class:

 template <typename T, typename X> class Base { protected: void func(X x) {} }; class Test : public Base<Test, int> { public: // typedef int X; }; 
+5
source

You have roundness that cannot be resolved with advanced ads. But it will work, although (I suspect) is not as well defined as you wanted.

 template <typename T> class Base { protected: template<typename Y> void func(Y x) {} }; class Test : public Base<Test> { public: typedef int X; }; 

If func were public, then you could write

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

which is satisfactory for any use of the Curiously Recurring Template that I think of.

+2
source

I'm not sure about this behavior, maybe someone can clarify this. But, as I understand it, at the moment you do : public Base<Test> , the name of type X does not exist (as indicated below).

If you create a wrapper class before creating the inheritance, the type will exist at the time of inheritance and an instance of the template will be created.

Compiles with 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 { }; 
+1
source

Source: https://habr.com/ru/post/983712/


All Articles