编译多个文件时出现奇怪的未定义引用错误
问题描述:
我想编写一个玩具程序来运行C++,但是我得到了一个奇怪的未定义的引用错误,我无法解决。编译多个文件时出现奇怪的未定义引用错误
我的代码由3个文件:
ex13_6.h:
#include<vector>
namespace ex13_6 {
template<class T> class Cmp {
public:
static int eq(T a, T b) {return a == b;}
static int lt(T a, T b) {return a < b;}
};
template<class T, class C = Cmp<T> > void bubble_sort(std::vector<T> &v);
}
ex13_6.cpp
#include<vector>
#include"ex13_6.h"
namespace ex13_6 {
template<class T, class C = Cmp<T> > void bubble_sort(std::vector<T> &v) {
int s = v.size();
T swap;
for (int i=0; i<s; i++) {
for (int j=0; j<s; j++) {
if (C::lt(v.at(j), v.at(i))) {
swap = v.at(i);
v.at(i) = v.at(j);
v.at(j) = swap;
}
}
}
}
}
main.cpp中:
#include"ex13_6.h"
#include<iostream>
#include<vector>
using namespace std;
using namespace ex13_6;
int main() {
// Sort using default comparison for int
vector<int> v_int;
for (int i=0; i<10; i++) {
v_int.push_back(10-i);
}
bubble_sort(v_int);
cout << "sort of int vector:\n";
for (vector<int>::const_iterator it = v_int.begin(); it != v_int.end(); it++) {
cout << ' ' << *it;
}
cout << '\n';
}
而且我编译使用:
g++ main.cpp -o main -std=gnu++0x ex13_6.cpp
以下是错误消息:
/tmp/ccRwO7Mf.o: In function `main':
main.cpp:(.text+0x5a): undefined reference to `void ex13_6::bubble_sort<int, ex13_6::Cmp<int> >(std::vector<int, std::allocator<int> >&)'
collect2: ld returned 1 exit status
我真的很感激任何帮助!
答
移动你的bubble_sort
模板的实施到你的头文件。
模板不像Java的泛型,所有的奇迹都发生在C++的编译时。为了使编译器为每个模板实例化生成代码,它必须是可见的,为此,它必须位于标题(或其他文件)中,并且包含在使用它的每个翻译单元中。
答
你的模板函数的定义应该是在ex13_6.h文件:
#include<vector>
namespace ex13_6 {
template<class T> class Cmp {
public:
static int eq(T a, T b) {return a == b;}
static int lt(T a, T b) {return a < b;}
};
template<class T, class C = Cmp<T> > void bubble_sort(std::vector<T> &v) {
int s = v.size();
T swap;
for (int i=0; i<s; i++) {
for (int j=0; j<s; j++) {
if (C::lt(v.at(j), v.at(i))) {
swap = v.at(i);
v.at(i) = v.at(j);
v.at(j) = swap;
}
}
}
}
}
答
您需要将模板实现放在头文件中。
当实例化一个模板时,编译器需要“看”实现,所以如果你只包含头部,实现需要在那里。
请勿包含.cpp文件。
您可能需要在'ex13_6.cpp'中显式模板实例,或者您应该将模板函数的实现移动到头文件'ex13_6.h'中。请参阅:http://*.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file – jxh 2013-04-30 20:16:16
谢谢@ user315052。但为什么我不能将通用模板函数定义放在ex13_6.cpp中? – user690421 2013-04-30 20:18:27
@ user690421:你可以,但你需要一个明确的实例,正如我所解释的。看到引用SO问题。 – jxh 2013-04-30 20:19:45