【问题标题】:How to use the overloaded "operator<<" properly?如何正确使用重载的“operator<<”?
【发布时间】:2019-12-29 04:04:53
【问题描述】:

c++中有一个模板类:

#include <iostream>
#include <vector>

using std::ostream;
using std::vector;

template<typename T>
class Business {
public:

    // default constructor
    Business() {
        customers.push_back(0);
    }

    // value constructor
    Business(vector<T> vec) {

        for (int i = 0; i < vec.size(); ++i)
            customers.push_back(vec[i]);
    }

    T getInfo(int i) const {
        if (i < 0 ) return 0;
        else return customers[i];
    }

    friend ostream &operator<<(ostream &os, const Business<T> &b) {

        std::string message = "";
        for (int i=0 ; i<b.customers.size() ; ++i) {
            message += b.getInfo(i) + " ";
        }
        return os << message;
    }

private:
    vector<T> customers;
};

但我收到以下关于 operator&lt;&lt; 正文的错误:

error: invalid operands to binary expression: message += b.getInfo(i) + " ";

收到该错误后,我将容易出错的代码行更改为:

message += b.getInfo(i)

然后错误是:

error: no viable overloaded '+=': message += b.getInfo(i)

编辑: 我有一个主要课程:

Business<Merchant<95>> bu({45, 87, 95, 23});
std::cout << bu << endl;

其中Merchant&lt;95&gt; 是另一个模板类。

我收到的错误如下:

in instantiation of member function 'operator&lt;&lt;' requested here: cout &lt;&lt; bu &lt;&lt; endl;

不知道怎么解决?

谢谢。

【问题讨论】:

  • std::string+= 运算符仅适用于其他字符串。如果T 不是std::string 或可以隐式转换为std::string 的东西,您应该会收到这样的消息。
  • 目前我可能误诊了。我目前无法重现您的问题。
  • 我需要了解更多你在做什么。要获得报告的错误消息,还应该有一些其他的错误消息。我也忘记了+= 可以接受chars 并且整数数据类型可以隐式转换为chars。在这种情况下没有错误消息,只是一个错误的答案。你能用minimal reproducible example 更新问题吗(假设minimal reproducible example 不会导致“D'oh!”时刻并且你修复了错误)?
  • 我还是看错了。一个整数加上一个字符串文字将是指针算术偏移到该字符串文字。示例:ideone.com/iCsUEX"ABC"const char[4]。它衰减到const char *,即内存中"ABC" 的地址。如果你在那个地址上加 1,你基本上就有一个字符串“BC”。但现在我正徘徊在喋喋不休的土地上。我想我应该停下来过夜。
  • 关键是标准类型Merchant,不管它是什么,都不是标准的。除非您有将int 0 转换为Merchant 的方法,否则if (i &lt; 0 ) return 0; 也应该有问题。我们还需要更多。请阅读minimal reproducible example 了解我们需要的更多信息。

标签: c++


【解决方案1】:

感谢所有花时间解决问题的人,我只需要在friend ostream &amp;operator&lt;&lt; 中更改for loop 的正文。因此,正确的做法如下:

friend ostream &operator<<(ostream &os, const Business<T> &b) {
        for (int i=0 ; i<b.customers.size() ; ++i) {
            os << b.getInfo(i);
        }
        return os;
}

【讨论】:

  • 要打印出空间使用os &lt;&lt; b.getInfo(i) &lt;&lt; ' ';
【解决方案2】:

如果不查看您的 Merchant 类模板,我无法提供修复。我可以告诉你问题是什么,

当您使用Merchant 实例化Business 时,您的类模板中的T 将替换为Merchant。编译器会剔除一个Business&lt;Merchant&gt;,该Business&lt;Merchant&gt; 将具有如下成员函数,除其他外,

   Merchant getInfo(int i) const {
        if (i < 0 ) return 0;
        else return customers[i];
    }

如您所见,getInfo 返回一个Merchent(返回的T 被替换为Merchent)。 现在这就是问题的根源。现在考虑以下内容,

        std::string message = "";
        for (int i=0 ; i<b.customers.size() ; ++i) {
            message += b.getInfo(i) + " ";
        }

message += b.getInfo(i); 中,message 的类型为string,而b.getInfo(i) 返回一个Merchant,就像我们之前看到的那样。编译器不知道如何将Merchant 转换为string 以将其添加到message。因此抛出no match for 'operator+='

解决方法是告诉编译器如何将Merchant 显式转换为字符串。这需要在Merchant 中定义operator std::string()

它可能看起来像这样,

Merchant<T>{
    ...
    public:
         operator std::string() const { 
             return to_string(MerchantID)+... }
    ...
};

这取决于您的Merchant 和其中包含的原始类型。见operator std::string() const?

【讨论】:

  • 对我的口味有太多猜测,但让我们看看这是怎么回事。
  • 谢谢@rranjik 和@user4581301 以及上面提供帮助的其他人,感谢您的帮助,我找到了答案,在friend ostream &amp;operator&lt;&lt; 和循环内,我只需要输入@ 987654349@ 然后返回 os.现在可以了!
【解决方案3】:

您收到的错误与您在其上实例化模板的类型(类)有关 - 在您的主要示例中为 Merchant - 而不是模板类 Businessem> 本身。

确保您已经在 Merchant 中定义了一个函数来将其转换为字符串,甚至是 char const*,这样您的代码就会编译通过。

【讨论】:

    猜你喜欢
    • 2022-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    • 1970-01-01
    相关资源
    最近更新 更多