我有一个关于在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
继承并使用 - 实例化它 - 说 - double
,
所以我相信"I know that -mainly due to complexity- virtual template methods aren't allowed."不具备不合格(不再是吗?C ++ 11? } / p>
它使用和不使用显式实例化-std=c++11
进行编译,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
。
强制非抽象成员进行部分模板实例化并将抽象实例的剩余实例留给子节点是否合法?在我年轻的天真中,我认为这应该是可行和合法的,但我们再次谈论C ++;编制者肯定会有所不同。
答案 0 :(得分:1)
问题不在虚函数中,而在于显式模板实例化。您必须在实现文件的底部放置显式模板实例化,因此它知道此时的所有实现细节:
// 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();
}