2016-09-23 105 views
0

編譯以下代碼時遇到此錯誤。 在做了一些研究並在不同情況下閱讀了類似的錯誤之後,我想出了我需要的解決方案。 但我沒有完全明白錯誤和修復的原因。模板繼承:沒有參數取決於模板參數

template <typename T> 
class TestA { 
    int a; 
    T temp; 

protected: 
    int b; 

public: 
    int c; 

    TestA(T te): a{10}, b{20}, c{30}, temp{te} {} 

    int geta(){ return a; } 
    int getb(){ return b; } 
    int getc(){ return c; } 
}; 

template <typename T> 
class TestB { 
    int atb; 
    T tempb; 

protected: 
    int btb; 

public: 
    int ctb; 

    TestB(T te) atb{10}, btb{20}, ctb{30}, tempb{te} {} 
}; 

template <typename T> 
class TestInh : public TestA<T>, public TestB<T> { 
    int aa; 
    T temptemp; 

protected: 
    int bb; 
    int b; 

public: 
    int cc; 

    TestInh(T te) : TestA<T>{te}, TestB<T>{te}, bb{10000}, b{-1000} {} 

    int get_total() { 
     // The error happens here! 
     return geta(); 
    } 
}; 

int main(int argc, char const *argv[]) { 
    char text = 'a'; 
    TestInh<char> test(text); 

    //std::cout << test.geta() << std::endl; 
    std::cout << test.get_total() << std::endl; 
    //std::cout << test.c << std::endl; 
    return 0; 
} 

當編譯這段代碼,我得到這個錯誤:

testtemplate.cc: In member function ‘int TestInh<T>::get_total()’: 
testtemplate.cc:54:32: error: there are no arguments to ‘geta’ that depend on a template parameter, so a declaration of ‘geta’ must be available [-fpermissive] 
int get_total() {return geta();} 
          ^
testtemplate.cc:54:32: note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated) 

它是通過調用this->geta(),而不是僅僅geta()解決,但我不完全理解爲什麼這不能由編譯器來解決。

有人能解釋我爲什麼嗎?

+0

它與VS2015 – GpG

+0

編譯@Gpg MSVC是錯誤的。不要依賴它來包含關鍵字'template'的所有內容。 –

回答

4

當擴展一個依賴於模板參數的類時,this種類變成了依賴名稱。

問題是,在執行兩階段名稱查找時,編譯器無法知道他在哪裏可以找到函數geta。他不知道它來自父母。因爲模板專業化是一件事情,所以TestA<int>TestA<double>可能是兩個完全不同的clas swith不同的功能和成員。

隨着this關鍵字的添加,編譯器知道geta必須是成員函數。

沒有它,它可能是成員函數或非成員函數,或者TestB的成員函數。

想象一下模板代碼,它將根據某些模板條件調用getaTestAgetaTestB。哎喲。編譯器希望確保代碼對於每個模板實例都是一致的。

說,以該函數作爲一個成員函數存在的編譯器的另一種方法是添加using語句:

template <typename T> 
struct TestInh : TestA<T>, TestB<T> { 
    // some code... 

    using TestA<T>::geta; 

    int get_total() { 
     // works! With the above using statement, 
     // the compiler knows that 'geta()' is 
     // a member function of TestA<T>! 
     return geta(); 
    } 
}; 
+0

謝謝!這是我正在尋找的。 – luisremis