Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

c++ - "Inherited" types using CRTP and typedef

The following code does not compile. I get an error message: error C2039: 'Asub' : is not a member of 'C'

Can someone help me to understand this?

Tried VS2008 & 2010 compiler.

template <class T>
class B
{
    typedef int Asub;

public:
 void DoSomething(typename T::Asub it)
 {

 }
};

class C : public B<C>
{
public:
 typedef int Asub;

};

class A
{
public:
 typedef int Asub;

};


int _tmain(int argc, _TCHAR* argv[])
{
 C theThing;
 theThing.DoSomething(C::Asub());

 return 0;
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You are being a bit unfair to the compiler here - C is incomplete without B<C> fully known and when processing B<C>, C is still an incomplete type. There are similar threads on comp.lang.c++.moderated and comp.lang.c++.

Note that it works if you delay the use by moving it into a member function definition, e.g.:

struct C : B<C> {
    void f() { typedef typename C::Asub Asub; }
};

You could work around the problem by either passing the types explicitly upward:

template<class T, class Asub> struct B { /* ... */ };
class C : B<C, int> { /* ... */ };

... or by moving them to some traits class if you need to pass more:

template<class T, class Traits> struct B {
  void DoSomething(typename Traits::Asub it) {}
};

struct CTraits {
    typedef int Asub;
};

struct C : B<C, CTraits> {
    typedef CTraits::Asub Asub;    
};

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...