与字符串(GCC)一起使用时对函数模板的未定义引用

时间:2009-03-05 10:22:47

标签: c++ string templates gcc stl

我需要在C ++中编写模板化函数replace_all,它将采用字符串,wstring,glibmm :: ustring等,并用{{search替换subject中所有出现的replace template < class T > T replace_all( T const &search, T const &replace, T const &subject ) { T result; typename T::size_type done = 0; typename T::size_type pos; while ((pos = subject.find(search, done)) != T::npos) { result.append (subject, done, pos - done); result.append (replace); done = pos + search.size (); } result.append(subject, done, subject.max_size()); return result; } 1}}。

replace_all.cc

#include <iostream>

template < class T >
T replace_all(
        T const &search,
        T const &replace,
        T const &subject
);

// #include "replace_all.cc"

using namespace std;

int main()
{
        string const a = "foo bar fee boor foo barfoo b";
        cout << replace_all<string>("foo", "damn", a) << endl;
        return 0;
}

test.cc

g++ -W -Wall -c replace_all.cc  
g++ -W -Wall -c test.cc  
g++ test.o replace_all.o  

当我尝试使用gcc 4.1.2

编译它时
test.o: In function `main':
test.cc:(.text+0x13b): undefined reference to `
   std::basic_string<char, std::char_traits<char>, std::allocator<char> >
   replace_all< std::basic_string<char, std::char_traits<char>, std::allocator<char> > >(
       std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&,
       std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&,
       std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&
   )
'
collect2: ld returned 1 exit status

我明白了:

#include "replace_all.cc"

但是当我在test.cc中取消注释g++ -W -Wall test.cc 并以这种方式编译时:

damn bar fee boor damn bardamn b

该程序链接并产生预期的输出:

{{1}}

为什么链接失败,我该怎么做才能使它工作?

2 个答案:

答案 0 :(得分:8)

您无法链接模板,因为编译器在某人尝试使用(实例化)模板之前不知道要生成哪些代码。

如果您知道要使用哪种类型或者您知道它们是有限的,您可以“询问”编译器实例化模板。
如果你想 - 把它放到你的.cc文件中:

template std::string replace_all( std::string const& search,
                                  std::string const& replace,
                                  std::string const& subject );


template glibmm::ustring replace_all( glibmm::ustring const& search,
                                      glibmm::ustring const& replace,
                                      glibmm::ustring const& subject );

答案 1 :(得分:6)

编译器需要在实例化时查看模板定义,否则无法生成专门用于实例化模板的类型的代码。正确的方法是像你一样实现模板函数in the header file or to #include the .cc的实现。