模板操作符重载函数上的未定义符号 [英] Undefined symbol on a template operator overloading function

查看:230
本文介绍了模板操作符重载函数上的未定义符号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个函数声明:

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

和此函数定义:

 命名空间a {
...
A类{
...
模板< class T& A&运算符<<(T);

我称为:

  a :: A b; 
b<< 1;

这是Makefile:

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

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

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


$ b b

它给了我:


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


为什么?

方案

T (即 int 在你的case)实际上是已知的。然而,这不是在 main.cpp 被编译之前的情况。在编译 A.cpp 时,模板函数不会实例化为实际函数,因此生成的对象文件不包括函数的二进制版本。



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


  1. 函数定义在头文件中。也就是说,make

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

    头文件的一部分,并从 .cpp 文件。



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

  2.  模板a :: A& a :: A :: operator<<(int out); 

    这将导致编译器实际实例化 A.cpp ,并将编译的函数包含在目标文件中。因此,链接器可以在链接 main.o A.o 时找到它,一切正常。缺点是它只适用于为您提供了显式实例化的特定类型(在这种情况下,只有 int )。



I have this function declaration:

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

and this function definition:

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

And I call it as:

a::A b;
b << 1;

and this is the 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

and it gives me:

Undefined symbols: a::A& a::A::operator<< <int>(int)

why is that?

解决方案

The function template will be turned into an actual function at compile time, once the type represented by T (that is, int in your case) is actually known. However, this is not the case before main.cpp is compiled. At the time when A.cpp is compiled, the template function is not instantiated into an actual function, therefore the object file generated doesn't include the binary version of the function.

There are two ways to solve this.

  1. Include the function definition in your header file. That is, make

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

    a part of the header file, and remove the function definition from the .cpp file.

    The effect of this is that any .cpp file that includes this header will be able to use any instantiation of the template, i.e. for any value of T.

  2. Alternatively, include an explicit template instantiation statement in A.cpp:

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

    This will cause the compiler to actually instantiate the template when A.cpp is compiled, and to include the compiled function in the object file. Hence the linker can find it when linking main.o and A.o together, and all is fine. The disadvantage is that it will only work for the specific types (in this case, only int) that you provided explicit instantiations for.

这篇关于模板操作符重载函数上的未定义符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆