[英]Overloading a C++ template class virtual function
下面是重新創建我遇到的問題的代碼。 Base
類是具有虛函數foo
的模板類。 foo
有一個默認實現,它添加傳入的參數。
SimpleDerived
派生自Base
,專門用於std::string
。 SimpleDerived
重載虛擬Base<T>::foo()
函數。 在main
調用時,此類將按預期編譯精細及其foo
輸出。
#include <iostream>
template<class T>
struct Base
{
virtual void foo(T val)
{
T local = val + val; // THE OFFENDING LINE OF CODE
std::cout << "Base" << std::endl;
}
};
struct SimpleDerived : public Base<std::string>
{
virtual void foo(std::string val)
{
std::cout << "SimpleDerived" << std::endl;
}
};
struct SimpleObject
{
int value;
};
struct ComplexDerived : public Base<SimpleObject>
{
virtual void foo(SimpleObject val)
{
std::cout << "ComplexDerived" << std::endl;
}
};
int main(void)
{
Base<int> base;
base.foo(2);
SimpleDerived simpleDerived;
simpleDerived.foo("hello world");
SimpleObject object;
ComplexDerived complexDerived;
complexDerived.foo(object);
return 0;
}
ComplexDerived
派生自Base
,專門使用自定義結構SimpleObject
。 ComplexDerived
重載foo
。 但是,這是問題的根源。 如果我嘗試編譯這個我得到:
quicktest.cpp: In member function ‘void Base<T>::foo(T) [with T = SimpleObject]’:
quicktest.cpp:47:1: instantiated from here
quicktest.cpp:8:19: error: no match for ‘operator+’ in ‘val + val’
顯然, SimpleObject
沒有運算符“+”。 但這是我的困惑..編譯器被要求實現Base<SimpleObject>::foo
因為這是ComplexDerived
繼承的。 但是,我從不使用或調用Base<SimpleObject>::foo
。 編譯器是否應該嘗試生成此基類函數?
C ++ 11標准的第14.7.1 / 10段規定:
實現不應隱式實例化函數模板,成員模板,非虛擬成員函數,成員類或不需要實例化的類模板的靜態數據成員。 如果虛擬成員函數不會被實例化,則實現是否隱式實例化類模板的虛擬成員函數是未指定的。 [...]
換句話說,這種情況下的行為是特定於實現的。
雖然理論上編譯器可能會發現不會調用對基類的foo()
實現的調用(因為函數調用不是通過引用或指針發生的)並且避免實例化它,這種行為不是強制性的按標准。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.