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

发布于 2024-07-15 08:45:00 字数 2248 浏览 2 评论 0原文

我需要用 C++ 编写一个模板化函数 replace_all ,它将接受字符串、wstring、glibmm::ustring 等,并替换 subject< 中出现的所有 search 。 /code> 替换为替换

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

为什么链接失败以及我该怎么做才能使其工作?

I need to write a templated function replace_all in C++ which will take a string, wstring, glibmm::ustring etc. and replace all occurrences of search in subject with replace.

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

When I try to compile this using gcc 4.1.2

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

I get:

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

But when I uncomment #include "replace_all.cc" in test.cc and compile this way:

g++ -W -Wall test.cc

The program links and produces expected output:

damn bar fee boor damn bardamn b

Why linking fails and what can I do to make it work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

天煞孤星 2024-07-22 08:45:00

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

如果您知道要使用哪些类型或者知道它们是有限的,您可以“要求”编译器实例化模板。
如果您愿意 - 将其放入您的 .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 );

You can't link templates as compiler don't know which code to generate before someone tries to use ( instantiate ) templates.

You can "ask" compiler to instantiate template if you knows which types are you going to use or if you know that they are limited.
If you want - put this to your .cc file:

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 );
岛歌少女 2024-07-22 08:45:00

编译器需要在实例化时查看模板定义,否则无法生成专门用于实例化模板的类型的代码。 正确的方法是将模板函数的实现 放在标头中文件或像您一样#include .cc

The compiler needs to see the template definition at the point of instantiation, else the code specialized for the type you instantiate the template with cannot be generated. The correct way is to put the implementation of the template functions in the header file or to #include the .cc like you did.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文