2009-03-05 100 views
3

我需要在C++编写一个模板函数replace_all这将需要一个字符串,wstring的,glibmm :: ustring等并用replace取代的search所有出现在subject未定义参考函数模板

replace_all.cc

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; 
} 

test.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; 
} 

当我尝试编译此使用gcc 4.1.2

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

我得到:

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 

但是,当我取消在test.cc #include "replace_all.cc"和编译这样:

g++ -W -Wall test.cc 

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

damn bar fee boor damn bardamn b 

为什么连接失败,我能做些什么,使工作?

回答

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);