c++ - 从 C++ 中的虚拟模板类继承

标签 c++ inheritance templates

如何在这段代码中继承虚拟模板类:

// test.h
class Base {
 public:
  virtual std::string Foo() = 0;
  virtual std::string Bar() = 0;
};

template <typename T>
class Derived : public Base {
 public:
  Derived(const T& data) : data_(data) { }

  virtual std::string Foo();
  virtual std::string Bar();

  T data() {
    return data_;
  }

 private:
  T data_;
};


typedef Derived<std::string> DStr;
typedef Derived<int> DInt;

// test.cpp
template<typename T>
std::string Derived<T>::Foo() { ... }
template<typename T>
std::string Derived<T>::Bar() { ... }

当我尝试使用 DStr 或 DInt 时,链接器提示有未解析的外部变量,即 Derived<std::string>::Foo()Derived<std::string>::Bar() , Derived<int> 也一样.

我的代码中是否遗漏了什么?

编辑: 谢谢大家。现在很清楚了。

最佳答案

你需要定义template<typename T> std::string Derived<T>::Foo() { ... }template<typename T> std::string Derived<T>::Bar() { ... }在头文件中。当编译器编译 test.cpp 时,它不知道 T 的所有可能值。您可能会在程序的其他部分使用它。

我认为有些编译器在编译和链接步骤之间存在联系,这些编译器注意到对缺少模板实例化的引用,并从声明它们的 .cpp 文件中实例化它们。但我不知道它们是什么,而且这种功能非常难找。

如果您在头文件中定义它们,大多数编译器会将它们作为“弱”符号发送到引用它们的每个编译单元中。并且链接器将抛出除弱符号的一个定义之外的所有。这会导致额外的编译时间。

或者,有显式实例化模板并强制编译器在此处发出定义的语法。但这需要您了解所有值 T可能有,但您不可避免地会错过一些。

关于c++ - 从 C++ 中的虚拟模板类继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1903055/

相关文章:

javascript - 我可以在 mustache.js 模板中调用全局函数吗?

c++ - CPP : Using UTF-8 in cURL

c++ - 使用 C++ 库的 Swift 中的 takeRetainedValue() 或 takeUnretainedValue()

c++ - try-catch block 可以在 LLVM/MSVC 上编译吗?

c++ - 一个类的所有实例都可以访问的变量

java - 为什么父类(super class)的实例可以放入子类的数组中?

c++ - 通过模板函数调用未知类型的方法

c++ - 如何在 header 中声明一个新类并在源文件中定义它而不会出现此错误?

ruby - ClassName <::在 ruby​​ 中意味着什么?

c++ - 当我创建一个模板时,我尝试使用它但是得到一个错误(C2668)和 IntelliSense 错误