2017-08-08 58 views
0

請考慮以下的例子基類類型參數方法:C++模板:找不到當超載

#include <iostream> 

class Base { 
public: 
    virtual void foo(std::string str) = 0; 
    void foo() { foo("LOL"); } 
}; 

class Derived : public Base { 
public: 
    void foo(std::string str) { std::cout << str << std::endl; } 
}; 

template<class T> class MyTemplate { 
public: 
    void print() { a.foo(); } 
    T a; 
}; 

int 
main(int argc, char** argv) 
{ 
    MyTemplate<Derived> a; 
    a.print(); 
} 

編譯時,我有以下錯誤:

main.cpp: In instantiation of ‘void MyTemplate<T>::print() [with T = Derived]’: 
main.cpp:24:11: required from here 
main.cpp:16:18: error: no matching function for call to ‘Derived::foo()’ 
    void print() { a.foo(); } 
       ^
main.cpp:16:18: note: candidate is: 
main.cpp:11:8: note: virtual void Derived::foo(std::string) 
    void foo(std::string str) { std::cout << str << std::endl; } 
     ^
main.cpp:11:8: note: candidate expects 1 argument, 0 provided 

它發現該溶液是寫:

void print() { a.Base::foo(); } 

但是爲什麼呢?爲什麼G ++不能自己找到Base :: foo()方法?

由於

+0

因爲'a.foo()'不帶任何參數,但是您的派生類函數'foo()'將'string'作爲參數。 –

+0

@克勞斯我想這不是那個笨蛋...... –

+0

@EdgarRokyan:葉普,你說得對。刪除了評論和投票...謝謝 – Klaus

回答

1

的原因是,方法fooDerived類隱藏與從Base類繼承的相同名稱的所有方法。因此,僅接受std::string作爲參數的方法foo的單一版本可用於通過Derived進行的呼叫。因此,你必須調用foo它不接受任何參數明確使用的語法:

a.Base::foo(); 

注意,你也可以使用using declaration作出繼承foo可見Derived類:

class Derived : public Base { 
public: 
    using Base::foo; 
    void foo(std::string str) { std::cout << str << std::endl; } 
}; 

有了這個更改下一個代碼變得有效:

a.foo();