[英]How to forward declare templated type that should belong to a class?
假設我有2個班:
class A
{
public:
typedef std::shared_ptr<A> Ref;
...
private:
B::Ref _b;
}
class B
{
public:
typedef std::shared_ptr<B> Ref;
...
private:
A::Ref _a;
}
這顯然需要B類和B :: Ref的前向聲明。 前向聲明B很簡單,但如何對B :: Ref也這樣做?
解決這個問題的方法之一是
class A;
class B ;
template <typename T>
struct Traits {
typedef std::shared_ptr<T> Ptr;
};
class A
{
private:
Traits<B>::Ptr _b;
};
class B
{
private:
Traits<A>::Ptr _a;
};
您無法轉發聲明嵌套的typedef
因為在前向聲明B
將是不完整的類型。 但是,您可以解決以下問題:
class B;
class A {
std::shared_ptr<B> _b;
public:
typedef std::shared_ptr<A> Ref;
};
class B {
A::Ref _a;
public:
typedef std::shared_ptr<B> Ref;
};
具有一個typedef“你這是怎么指向對象X
”類中X
是一個不好的設計決策,正是因為你需要的完整定義X
看看它的成員,但你希望能夠指X
不充分定義。
我可以看到解決這個問題的兩種方法。 一種是放棄范圍界定並簡單地調用typedef RefA
,定義類在前向聲明的位置:
class A;
typedef std::shared_ptr<A> RefA;
或者,您可以將“知道如何引用”委托給單獨的類。 你可以把它變成一個類模板,這樣類仍然可以在那里注冊自己喜歡的引用類型:
template <class T>
struct RefT
{
typedef T *type; // Default reference type
};
template <class T>
using Ref = typename RefT<T>::type;
class A;
template <>
struct RefT<A>
{
typedef std::shared_ptr<A> type;
};
class B
{
private:
Ref<A> _a;
};
不幸的是,你無法轉發聲明嵌套的typedef。 但是,你可以使用全局typedef,比如
typedef std::shared_ptr<B> RefB ;
等等。 其他解決方案是使用后期模板專業化,如下所示:
template <typename T> class BImpl;
template <typename T>
class AImpl
{
public:
typedef std::shared_ptr<AImpl> Ref;
private:
typename BImpl<T>::Ref _b;
};
template <typename T>
class BImpl
{
public:
typedef std::shared_ptr<BImpl> Ref;
typename AImpl<T>::Ref _a;
};
typedef AImpl<void> A;
typedef BImpl<void> B;
當我想轉發typedef時,我總是考慮繼承。 它可能看起來像這樣:
template<typename T>
class Ref : public std::shared_ptr<T>
{
Ref()
{}
Ref(T *t)
: std::shared_ptr<T>(t)
{}
};
class B;
class A
{
public:
//...
private:
Ref<B> _b;
};
class B
{
public:
//...
private:
Ref<A> _a;
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.