有谁知道如何欺骗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
{
};
}
答案 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;
};