c++ - 抽象类的模板实例化

标签 c++ templates inheritance

我有一个关于在 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/

相关文章:

c++ - 在 OpenGL 中使用过剩的 vsync 问题

c++ - 我可以使用模板参数作为非模板方法的参数吗?

c++ - 父类(super class)的指针如何访问子类的变量?

python - python 菱形继承(钻石问题)中的 super() 奇怪行为

c++ - 如何决定堆栈中的内容?

c++ - 为什么 "static"关键字在 C 和 C++ 中有这么多含义?

c++ - 在模板中创建复制链表的函数时遇到问题

c++ - 构造函数使用可变数量的右值引用

javascript - 仅动态更改容器的选择性部分

python - 如何 pickle 继承自 A 的类 B(具有许多变量)的对象,该对象定义了 __setstate__ 和 __getstate__