我有一个关于在 C++ 中混合模板和继承的问题,我不确定我正在做的事情是否被标准禁止,或者只是一个实现问题,或者我犯了一个错误。
在浏览SO上的相关问题时,我发现很多snippets都不是最小的,或者被遗忘的问题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
实例化它,
所以我相信"I know that -mainly due to complexity- virtual template methods aren't allowed."不持有不合格(也许不再是?C++11?我不需要使用任何 -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
但是,如果这是明确定义且合法的,则应该有一个 Foo<double>::doSomething()
的实现某处。
问题
强制对非抽象成员进行部分模板实例化并将抽象成员的剩余实例化留给 child 是否合法?在我幼稚的天真中,我认为这应该是可行和合法的,但是我们又在谈论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();
}
关于c++ - 抽象类的模板实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26633198/