[英]Protected member is unknown for derived class
我找到了Graphs的開源類庫。 當我將它包含在我的項目中時,它有很多錯誤,我試圖修復它們。 但是有一個編譯錯誤,我無法解決它。
基類:
template <typename K, typename W, typename T>
class _base_graph
{
//...
protected:
std::map<K, T> nod;
std::list<edge> edg;
};
派生類:
template <typename K, typename T = void*>
class graph : public _base_graph<K, void*, T>
{
//...
public:
void add_edge(const K& k1, const K& k2);
};
方法體:
template <typename K, typename T>
void graph<K, T>::add_edge(const K& k1, const K& k2)
{
if (nod.find(k1) == nod.end() || nod.find(k2) == nod.end()) // <-- error!!
throw std::string("add_edge: Node does not exist");
// ...
}
但我的gcc編譯器顯示錯誤:
錯誤:未在此范圍內聲明'nod'
您可以在此在線編譯器中查找並測試mycode。
你需要
this->nod.find(k2);
要么
_base_graph<K, void*, T>::nod.find ....;
基類和派生類是模板,在您的代碼中, nod
是一個非依賴名稱,因此在graph
的聲明中查找。 這是兩階段查找的第一階段。 在這個階段,編譯器(如果它遵循標准的名稱查找規則)不可能知道nod
含義, 因為它在第二階段之前不考慮基類 。 所以有必要告訴編譯器應該在第二階段查找nod
。 為此,我們通過使用上面的一種形式明確告訴它nod
在基類中。
這種行為的原因是,在派生類的定義時 ,不應該知道_base_graph<K, void*, T>::
contains是什么,以允許添加甚至隱藏名稱的模板的特化。 因此,上面的技巧確保在所有信息都可用時,在派生類的實例化時查找名稱。
總之,這里有兩個問題:
nod
不是一個依賴名稱,所以它將在第一階段查找。 nod
的基類模板在第二階段之前不可用,因此無法解析名稱。 通過使用this->nod
或_base_graph<K, void*, T>::nod
,我們顯式處理依賴名稱,強制查找在第二階段進行。
請參見此處的第 7點至第10點。
感謝@ DavidRodriguez-dribeas澄清了兩階段查找的一些細節。
nod
是依賴基礎的成員(依賴於模板參數的基礎)。 您需要使用基本名稱限定調用,例如_base_graph<K, void*, T>::nod
或使用this->nod
。
或者,您也可以在函數或類范圍中using _base_graph<K, void*, T>::nod
引入名稱。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.