2009-03-05 8 views
3

私は、文字列、wstringの、glibmm :: UStringでなどを取り、replacesubjectsearchの出現をすべて置き換えますCでテンプレート機能replace_allを++記述する必要があります。文字列(GCC)で使用する場合、テンプレートを機能させるに未定義の参照

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

コンパイラはインスタンス化の時点でテンプレート定義を参照する必要があります。そうでないと、テンプレートをインスタンス化する型に特化したコードを生成できません。正しい方法は、あなたのようにテンプレート関数in the header file or to #include the .ccの実装を置くことです。

関連する問題