有人可以向我解释为什么下面的内容不能编译吗?希望显而易见的是我错过了......
functions.hpp:
template<typename T> string vector_tostr(std::vector<T> v);
functions.cpp:
template<typename T> string vector_tostr(std::vector<T> v){
std::stringstream ss;
std::string thestring = "";
if(v.size() > 0){
ss << "[";
for(size_t i = 0; i < v.size(); i++){
if(i != 0)
ss << " ";
ss << v[i];
}
ss << "]";
thestring = ss.str();
}
return thestring;
}
的main.cpp
#include "functions.hpp"
int main(int argc, char *argv[]){
vector<int> thevector;
thevector.push_back(1);
thevector.push_back(2);
string result = vector_tostr(thevector);
//I have also tried vector_tostr<int>(thevector)
}
我得到的神秘错误如下:
架构x86_64的未定义符号:“std :: basic_string,std :: allocator&gt; vector_tostr(std :: vector&gt;)“,引用 从: _main in main.o ld:找不到架构的符号x86_64 collect2:error:ld返回1退出状态make: * [main]错误1
答案 0 :(得分:4)
模板在编译时实例化。编译器所做的是为代码中使用的每个模板参数值创建一个重载方法。例如,使用int
和double
作为模板参数将从同一定义创建两个重载方法,仅在参数类型中有所不同。因此编译器必须能够在编译时看到定义。你可以用几种方式做到这一点
答案 1 :(得分:3)
您需要将函数模板的实现显示在使用它的位置。否则,编译器不知道如何在给定类型的情况下实例化函数。
将函数定义放在functions.hpp
中。没有使用functions.cpp
。
答案 2 :(得分:3)
不允许以与普通函数相同的方式分隔模板化函数的声明和定义('。hpp'文件中的声明,'。cpp'文件中的定义)。有几种方法可以解决这个问题。
您可以在头文件中的相同位置声明和定义函数。
OR
您可以在名为functions.inl
的文件中尝试此操作:
template<typename T>
inline string vector_tostr(std::vector<T> v){
std::stringstream ss;
std::string thestring = "";
if(v.size() > 0){
ss << "[";
for(size_t i = 0; i < v.size(); i++){
if(i != 0)
ss << " ";
ss << v[i];
}
ss << "]";
thestring = ss.str();
}
return thestring;
}
然后,在头文件(functions.hpp
)的末尾,输入:
#include "functions.inl"
.inl
是内联头文件的文件扩展名。您可以使用它来分隔声明
和模板化函数的定义。