我有一個嵌套類定義,我想將它作為父類(包含嵌套類的類,而不是被繼承的類)模板引數傳遞下去。由于模板似乎不知道嵌套類的存在,我試圖將它作為一個不完整的型別傳遞下去,只是后來讀到這樣做通常是一個壞主意,而且很少被允許(例如在shared_ptr)。
我知道這可以很容易地通過簡單地在外部宣告嵌套類來解決(這就是我所做的)但我問這個是因為我想知道是否有任何方法可以達到相同的效果,因為我喜歡他們是如何做的不要污染命名空間,它們是如何與父類定義“關聯”而不暴露任何東西的。
這是一個例子,也許可以更清楚地說明我在說什么:
#include <memory>
using namespace std;
template <class T> class shared_class {
protected:
shared_ptr<T> d = make_shared<T>();
T* container() { return d.get(); }
};
// A is the "parent" class.
class A : public shared_class<C> { // Compiler error: C is undefined.
// Similarly, A::C will complain that no C is in A.
class C { // Nested class
public:
int i = 0;
};
};
是否有另一種使用模板的方法,即嵌套類的整個定義完全包含在父類定義中?
uj5u.com熱心網友回復:
簡而言之:不,你不能這樣做。您可以在 SO 上找到一些類似的問題,但這一切都歸結為能夠前向宣告嵌套類,沒有定義就無法做到這一點。例如看這個問題。
換句話說,只要揮手,你可能會認為你可以做這樣的事情:
class A;
class A::C; // Error: not real C
class A : public shared_class<A::C> { // Error: incomplete base class
class C {
public:
int i = 0;
};
};
但你不能。您需要將 的宣告分開C,如果要將其用作基類,則需要對其進行定義。另請參閱此類問題。
如果它只是您最關心的名稱空間封裝,您總是可以使用專用namespace的,這就是它們的用途。
uj5u.com熱心網友回復:
據我所知,您給出的要求沒有針對您的具體案例的解決方案。
直接使用C作為模板引數不能以任何方式作業,僅僅是因為那時編譯器還沒有看到它C被宣告為成員類,A并且因為在該點之前沒有辦法宣告嵌套類。
它在您的特定情況下不起作用,但有一些限制,您可以shared_class通過特征模板或直接通過別名宣告向模板引數的型別添加間接,這將允許您延遲T應該的確定C直到定義A并保留為C嵌套類之后。
不幸的是,如果您想在將使用類模板專業化實體化的宣告之一中使用 的型別T,那么這不起作用,這里和。后者可以通過宣告回傳型別來保存,但前者不能。shared_classshared_ptr<T> dT* container()auto
這個想法是讓shared_classusetypename T::shared_class_type無處不在,而不是T.
該類A將被定義為
class A : public shared_class<A> {
public:
class C {
public:
int i = 0;
};
using shared_class_type = C;
};
或者,您可以定義一個template<typename T> struct shared_class_traits;, 可能帶有一個默認實作,包含在其定義后using shared_class_type = typename T::shared_class_type;可能專門用于成員,以便可以在任何地方使用。這比使用“保留”所有類的特定成員名稱更靈活。Ausing shared_class_type = A::C;shared_classtypename shared_class_traits<T>::shared_class_typeshared_class_type
但正如我上面解釋的那樣,只要在shared_class使用shared_class_type類模板特化實體化的背景關系中使用,它就不會起作用。因此,在成員函式體或默認成員初始化程式內部會很好,但在資料成員或成員函式型別中則不行。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/491518.html
上一篇:布爾狀態變數更改導致父組件消失?
