C ++函数模板,体系结构的未定义符号

时间:2014-05-26 03:35:36

标签: c++ templates

有人可以向我解释为什么下面的内容不能编译吗?希望显而易见的是我错过了......

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

3 个答案:

答案 0 :(得分:4)

模板在编译时实例化。编译器所做的是为代码中使用的每个模板参数值创建一个重载方法。例如,使用intdouble作为模板参数将从同一定义创建两个重载方法,仅在参数类型中有所不同。因此编译器必须能够在编译时看到定义。你可以用几种方式做到这一点

  1. 在标题中完全定义
  2. 定义为ex。 .impl文件并将其包含在声明标题中
  3. 在.cpp文件中使用模板参数进行显式实例化,在这种情况下,只能使用实例化版本。

答案 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是内联头文件的文件扩展名。您可以使用它来分隔声明 和模板化函数的定义。