[英]Template instantiation of abstract class
我對C ++中的模板混合和繼承有疑問,我不確定標准是否只允許我做什么,或者只是實現一項事情,還是我弄錯了。
在瀏覽有關SO的相關問題時,我發現許多代碼片段不是很簡單,或者是被遺忘的template<>
或諸如此類的事情(沒有指責,我始終對模板語法感到困惑) 。 因此,我試圖將其歸結為一個最小的概念性問題。
我有一個模板化的抽象類Foo
// Foo.hpp
template <typename T>
class Foo
{
virtual T doSomethingAbstract() = 0;
T doSomething();
};
和
#include "Foo.hpp"
template class Foo<double>;
template <typename T>
T Foo<T>::doSomething()
{
// implementation
}
當我將實現放入頭文件時 ,這對於gcc(4.7和4.8)和clang(3.4)可以正常工作,即我可以從Foo
繼承並使用-say- double
實例化它,因此我相信“我知道-主要是由於到復雜性-不允許使用虛擬模板方法。” 不持有不合格(不再可能?C ++ 11?我沒有使用任何需要-std=c++11
左右,它的工作原理沒有)。
它可以在有或沒有顯式實例化template class Foo<double>;
情況下進行編譯template class Foo<double>;
nm
告訴我(僅)通過顯式實例化實際生成了一些代碼,例如
$ nm -C Foo.o
U __cxa_pure_virtual
0000000000000000 V typeinfo for Foo<double>
0000000000000000 V typeinfo name for Foo<double>
0000000000000000 V vtable for Foo<double>
U vtable for __cxxabiv1::__class_type_info
但是,如果定義明確且合法,則應該在某處實現Foo<double>::doSomething()
。
對非抽象成員強制部分模板實例化並將抽象實例的其余實例實例留給子代是否合法? 在我年輕的時候,我認為這應該是可行和合法的,但是接下來我們又在談論C ++。 編譯器肯定會有所不同。
問題不在於虛函數,而在於顯式模板實例化。 您必須在實現文件的底部放置顯式模板實例化,因此它知道此時的所有實現細節:
// Foo.cpp
#include "Foo.h"
template <typename T>
T Foo<T>::doSomething()
{
return doSomethingAbstract();
}
template class Foo<double>;
// main.cpp
#include "Foo.h"
class Foo2 : public Foo<double> {
public:
double doSomethingAbstract() {
return 0;
}
};
int main() {
Foo2 foo;
foo.doSomething();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.