使用父类定义的类型的基类

时间:2010-12-06 18:08:22

标签: c++ templates typedef mixins

我有一个Visual Studio 2008 C ++应用程序,其中基类A_Base需要实例化一个类型由父类定义的数据成员。例如:

template< typename T >
class A_Base
{
public: 
    typedef typename T::Foo Bar; // line 10

private:
    Bar bar_;
};

class A : public A_Base< A > 
{
public:
    typedef int Foo;
};

int _tmain( int argc, _TCHAR* argv[] )
{
    A a;
return 0;
}

不幸的是,看起来编译器不知道T::Foo是什么,直到为时已晚,我得到这样的错误:

1>MyApp.cpp(10) : error C2039: 'Foo' : is not a member of 'A'
1>        MyApp.cpp(13) : see declaration of 'A'
1>        MyApp.cpp(14) : see reference to class template instantiation 'A_Base<T>' being compiled
1>        with
1>        [
1>            T=A
1>        ]
1>MyApp.cpp(10) : error C2146: syntax error : missing ';' before identifier 'Bar'
1>MyApp.cpp(10) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>MyApp.cpp(10) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

有没有办法实现这种功能?

谢谢, PaulH

3 个答案:

答案 0 :(得分:5)

A_Base<A>A尚未完成的位置实例化:

class A : public A_Base< A >

您可以考虑使用特征类:

template<class T> struct traits;

template< typename T >
class A_Base
{
public: 
    typedef typename traits<T>::Foo Bar; // line 10

private:
    Bar bar_;
};

class A; // Forward declare A

template<> // Specialize traits class for A
struct traits<A>
{
    typedef int Foo;
};

class A : public A_Base< A > {};

int main()
{
    A a;
}

答案 1 :(得分:3)

您可以尝试以下操作:

template< typename T >
class A_Base
{
public: 
    typedef typename T::Foo Bar; // line 10

private:
    Bar bar_;
};

class A_Policy
{
public:
    typedef int Foo;
};

class A : public A_Base<A_Policy>
{};

int _tmain( int argc, _TCHAR* argv[] )
{
    A a;
return 0;
}

答案 2 :(得分:1)

A取决于类A_Base,它取决于类A ...等。您在这里有一个递归。您需要在单独的类中声明Foo

class A;

template<typename T> struct Foo;
template<> struct Foo<A> { typedef int type; };

template< typename T >
class A_Base
{
public: 
    typedef typename Foo<T>::type Bar; // line 10

private:
    Bar bar_;
};

class A : public A_Base< A > 
{
};

另见GotW #79