内部类模板循环引用

时间:2011-06-28 03:58:27

标签: c++ templates

有谁知道如何欺骗C ++编译器来编译类似的东西(条件是TheObservedObject保留在MyClass中):

template< typename Type >
class Observabile
{
public:
   typename typedef Type::TheObservedObject TheObject;

   void Observe( TheObject& obj ) {}
};

class MyClass : public Observabile< MyClass >
{
public:
   class TheObservedObject
   {
   };
}

3 个答案:

答案 0 :(得分:1)

可悲的是,这不是直接可能的,因为MyClass在实例化Observable时尚未完成,因此您无法访问任何typedef。你可以通过添加一个小包装来解决这个问题:

template< typename Type, typename Wrapper >
class Observable
{
public:
   typename typedef Wrapper::TheObservedObject TheObject;

   void Observe( TheObject& obj ) {}
};

struct MyClassWrapper{
   class TheObservedObject
   {
   };
};

class MyClass : public Observable< MyClass, MyClassWrapper>
{
public:
    typedef MyClassWrapper::TheObservedObject TheObservedObject;
};

或者只是将TheObservedObject放在MyClass(Wrapper)之外。

答案 1 :(得分:1)

您既不能转发声明内部类,也不能从template Observable访问它们作为不完整类型。但是,在这种情况下,你可以有一个技巧。

// make inner class external
class TheObservedObject
{
  private: // make everything private
  friend class MyClass;  // make friends with original outer class
};

因此,只有TheObservedObject才能访问MyClass

现在您可以更改class Observabile<>接受2个参数并传递上述类。这可能会带来某些限制,但它可能非常接近。

答案 2 :(得分:1)

正如其他人所说,MyClass在实例化Observable时不完整。但是,您可以使用traits类。这样的事情可能有用:

template<class T>
struct ObservedObject {};

template<class T>
class Observable
{
public:
    typedef typename ObservedObject<T>::type TheObject;

    void Observe(TheObject& obj) {}
};

class MyClass;  // forward decl

class MyClassObservedObject
{
    // define outside of MyClass
};

template<> struct ObservedObject<MyClass>
{
    typedef MyClassObservedObject type;
};

class MyClass : public Observable<MyClass>
{
    //
    // ...
    //

private:
    friend class MyClassObservedObject;
};