【问题标题】:Error "Undefined reference to operator<<" in C++ codeC++ 代码中的错误“未定义对运算符 << 的引用”
【发布时间】:2020-07-20 12:25:05
【问题描述】:

我编写了一个简单的运算符重载函数,如果我在类中定义它(块注释),它工作正常,但如果在类外定义,则会出错。知道错在哪里吗?

#include<iostream>

using namespace std;


template<class T>
class vector{
    
    int d;
public:
    vector(){
        d = 0;
    }
    vector(T data){
        d = data;
    }
    
    friend void operator << (vector &v, T data);
    /*{
        cout << data << endl;
    }*/
    
};

template<class T>
void operator << (vector<T> &v, T data){
    
    cout <<  data;
}


int main(){
    
    vector<int> v1;
    v1 << 10;
    
    return 0;
}

【问题讨论】:

  • 可能编译器无法区分std::vector和你的vector类?
  • using namespace std; — 不要这样做。即使不太可能,&lt;iostream&gt; 也可以包含 &lt;vector&gt;
  • 您遇到什么错误?请edit您的问题具体。我收到了警告、通知和未定义的引用。 ideone.com/cXFacq如果你仔细阅读它们,你可能会发现哪里出了问题。
  • Why is “using namespace std;” considered bad practice? 它很快就会用vector 这样的名字咬你。不要使用它。

标签: c++ class templates operator-overloading friend-function


【解决方案1】:

类模板定义中的这个友元函数声明

friend void operator << (vector &v, T data);

不是一个模板函数(虽然它是一个模板实体,如果它是在类中定义的)。

另一方面,这个声明在类模板定义之外

template<class T>
void operator << (vector<T> &v, T data){
    
    cout <<  data;
}

定义一个模板函数。

要么在类定义中定义友元函数。在这种情况下,编译器将为每个使用的类模板特化生成函数的定义。或者对于每个使用的类特化,您必须自己明确定义(提供)一个单独的非模板友元函数。

这是一个演示程序

#include<iostream>

template<class T>
class vector{
    
    int d;
public:
    vector(){
        d = 0;
    }
    vector(T data){
        d = data;
    }
    
    friend void operator << (vector &v, T data);
    /*{
        cout << data << endl;
    }*/
    
};

template<class T>
void operator << (vector<T> &v, T data)
{    
    std::cout <<  data;
}

void operator << (vector<int> &v, int data)
{    
    std::cout <<  data;
}

int main()
{
    
    vector<int> v1;
    v1 << 10;
    
    return 0;
}

程序输出是

10

程序中有两个重载函数operator &lt;&lt;。第一个是在类定义中声明的友元非模板函数,第二个是不是类友元函数的模板函数。对于 main 中使用的类特化 vector&lt;int&gt;,您必须在类外提供非模板友元函数定义。

或者你可以在类中定义朋友函数。

【讨论】:

  • 我猜你是。我被这个答案弄糊涂了,抱歉。
【解决方案2】:

问题是如何将一个模板添加到其他模板。

没有友谊your code works(你不能访问私处)。

要修复它,您必须为模板添加好友,而不是常规函数。由于您定义的函数是模板友谊声明,因此必须表达这一点。


template<class T>
class vector{
    
    int d;
public:
    ...

    template<typename U>
    friend void operator<<(vector<U> &v, U data);
};

https://godbolt.org/z/oxcojb

题外话
我个人避免友谊(我不记得在我的代码中使用过它)。你的代码我会做like this

【讨论】:

  • 是的,它解决了我的问题。您是对的,无法将模板功能应用于另一个模板。谢谢。
【解决方案3】:

如果你是using namespace std,然后定义了一个名为 vector 的类,它是 std 命名空间中的一个名称,编译器将不知道要使用哪一个,这将导致未定义的行为,或者我认为。

另外,您收到错误是因为您需要在类中定义该函数,因为您使用的是模板。

【讨论】:

  • 虽然第一部分通常是正确的,但这不是这里的直接问题。这将导致不同的消息(关于“模棱两可的过载”)。并且没有规则必须内联定义模板,问题是friend 声明没有从它声明的类中获得template。GCC 对此问题有一个很好的详细警告:wandbox.org/permlink/6t8KV2rCm8wCrHcK跨度>
猜你喜欢
  • 1970-01-01
  • 2012-06-24
  • 1970-01-01
  • 1970-01-01
  • 2017-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多