簡體   English   中英

從類模板訪問繼承的對象

[英]Accessing inherited objects from class template

我一直在學習C ++模板,我遇到了一些奇怪的行為。 考慮這個類結構(從我的原始代碼中刪除):

class A {
public:
    std::vector <int> vec;
};

template <typename T> class B : public A {  };

template <typename T> class C : public B<T> {
public:
    using A::vec;
    int test() {
        return vec[1];      // OK
    }

    int test2() {
        return vec.size();  // error: 'class A' has no member named 'size'
    }
};

編譯時,我在test2得到一個錯誤,說class A沒有成員size 但是vec應該是一個vector對象,而不是A的實例。 實際上,如果我直接從A而不是B<T>派生C ,或者從C刪除模板,那么它編譯得很好。

此外,如果我將以下方法添加到C

int test3() {
    void ***v = vec;        // error: cannot convert from
                            // 'std::vector<int,...>'  to 'void***' 
}

編譯器說它無法從vector<int>轉換為void*** ,因此它似乎知道vec的正確類型。 我在這里犯了錯誤,或者這可能是我的編譯器中的錯誤? 我正在使用Apple版的g ++ 4.2.1。 編輯:似乎也出現在g ++的更高版本中。

謝謝你的幫助!

第二次編輯 :如果我在test2使用this->vec.size()而不是依賴於using A::vec聲明,我的編譯器很高興。

首先,你的代碼用clang編譯( 在這里看到),不用gcc編譯。 我也用VS2013編譯它。


您的原始問題與編譯器在模板中查找名稱的方式有關。

標准§14.6.2:

模板定義中使用的非依賴名稱可以使用通常的名稱查找找到,並在使用它們時綁定。

此外, C ++ FAQ有一個很好的條目:

查找非依賴名稱(如vec)時,編譯器不會查找依賴的基類(如B)。


方案

1.使用this->vec (這總是隱含地依賴於模板)

int test2() {
    return this->vec.size();  
}

2.使用using B<T>::vec

3.直接使用B<T>

int test2() {
    return B<T>::vec.size();  
}

筆記:

  • 我不確定為什么gcc拒絕using A::vec; ,看起來像一個編譯器錯誤(並注意using B<T>::A::vec;工作)。
  • 模板名稱查找的標准參考:§14.6.3和§14.6.4

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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