c++ - 模板类继承链接器错误

标签 c++ templates inheritance c++11 linker-errors

假设我有一个类模板A,以及从A 继承的非模板类B。虽然 A 编译正常,但编译 B 会触发链接器错误。具体来说,

A.hpp

#ifndef A_HPP_INCLUDED
#define A_HPP_INCLUDED

template <typename T>
class A { 
public:
    A();
    A(A<T>&& );
    virtual ~A();

    /* ... */
protected:
    T x;
};
#include A.tpp
#endif

A.tpp

#include "A.hpp"

template <typename T>
A<T>::A() { ... }

template <typename T>
A<T>::A(A<T>&& other)
   : x(std::move(other.x)) { }

template <typename T>
A<T>::~A() { ... }

测试A.cpp

#include "A.hpp"

int main() {

    A<std::string> a;

    /* ... */

    return 0;
}

编译testA.cpp如下成功:

$ g++ -std=c++11 testA.cpp <- OK

接下来是从 A 继承的非模板 class B:

B.hpp

#ifndef B_HPP_INCLUDED
#define B_HPP_INCLUDED
#include "A.hpp"
class B
    : public A<std::string> {
public:
    B();
    virtual ~B();

    static A<std::string> foo();
};
#endif

B.cpp

#include "B.hpp"

B::B()
    : A(std::move(foo())) { }

B::~B() { }

A<std::string> B::foo() { ... }

测试B.cpp

#include "B.hpp"

int main() {
    B b;

    /* ... */

    return 0;
}

testB.cpp 的编译似乎没问题,但链接器不是一个快乐的露营者:

尝试 1

$ g++ -std=c++11 testB.cpp   
Undefined references to B(), and ~B()
collect2: error: ld returned 1 exit status

尝试 2

$ g++ -std=c++11 testB.cpp B.cpp
Undefined reference to B.foo()
collect2: error: ld returned 1 exit status

非常感谢任何帮助/想法。 ld 先生让我彻夜难眠,威胁着我的理智。

编辑

谢谢迈克·西摩!这个最小的示例并不是真实代码的真实再现,因为在实现中确实缺少限定符,并且是齿轮中的 Spanner 。

最佳答案

我建议您分两次进行编译和链接:

g++ -c -std=c++11 -o B.o B.cpp
g++ -c -std=c++11 -o TestB.o TestB.cpp
g++ -o test.exe B.o TestB.o

如果我的建议中断,它至少会清楚哪里缺少什么,您将能够使用 nm 调试单个目标文件。

关于c++ - 模板类继承链接器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19789575/

相关文章:

c++ - std::runtime_error 是否复制构造函数中传递的字符串?

c++ - 了解 getopt() 示例。 int 与 char 的比较

c++ - 如何在C++中将不同模板类型的对象相乘

ruby-on-rails - 查找后的 Mongoid 文档持久性

oop - 何时使用接口(interface)而不是抽象类,反之亦然?

C++ wstringstream << NULL

c++ - 模板仿函数与函数

c++ - 是否有可以无限期编译的 C++ 代码?

C++11 虚拟析构函数和 move 特殊函数的自动生成

c++ - C++11 的移动语义是否优于写时复制习惯用法?