模板运算符重载函数上的未定义符号

2023-12-24

我有这个函数声明:

template<class T>
a::A& a::A::operator<<(T out) {
    std::cout << out;
    return (*this);
}

这个函数定义:

namespace a {
    ...
    class A {
        ...
        template<class T> A& operator<<(T);

我称之为:

a::A b;
b << 1;

这是 Makefile:

app: main.o A.o
    g++ main.o A.o -o app

main.o: main.cpp
    g++ -c main.cpp

A.o: A.cpp
    g++ -c A.cpp

它给了我:

未定义符号:a::A& a::A::operator(int)

这是为什么?


一旦由 表示的类型,函数模板将在编译时变成实际的函数T(那是,int在你的情况下)实际上是已知的。然而,之前的情况并非如此main.cpp已编译。当时当A.cpp编译后,模板函数不会实例化为实际函数,因此生成的目标文件不包含该函数的二进制版本。

有两种方法可以解决这个问题。

  1. 将函数定义包含在头文件中。也就是说,使

    template<class T>
    a::A& a::A::operator<<(T out) {
        std::cout << out;
        return (*this);
    }
    

    头文件的一部分,并从头文件中删除函数定义.cpp file.

    这样做的效果就是any .cpp包含此标头的文件将能够使用any模板的实例化,即对于任何值T.

  2. 或者,在中包含显式模板实例化语句A.cpp:

    template a::A& a::A::operator<<(int out);
    

    这将导致编译器在以下情况下实际实例化模板:A.cpp被编译,并将编译后的函数包含在目标文件中。因此链接器在链接时可以找到它main.o and A.o在一起,一切都很好。缺点是它仅适用于特定类型(在本例中,仅适用于int)您为其提供了显式实例化。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

模板运算符重载函数上的未定义符号 的相关文章

随机推荐