簡體   English   中英

受保護的成員對於派生類是未知的

[英]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是什么,以允許添加甚至隱藏名稱的模板的特化。 因此,上面的技巧確保在所有信息都可用時,在派生類的實例化時查找名稱。

總之,這里有兩個問題:

  1. nod不是一個依賴名稱,所以它將在第一階段查找。
  2. 聲明為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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM