C ++重载“ <<”不适用于输出“ obja + objb”

时间:2019-11-29 13:35:12

标签: c++

我为我的课重载了“ <<”和“ +”运算符。如果我使用cout<<a;输出单个对象,则效果很好。但是当我输出cout<<a+b;

时失败

g ++版本:g ++(GCC)9.2.0

class UTF8string{
    private:
        string data;
    public:
        UTF8string();
        UTF8string(string a);
        int bytes();
        int find(string a);
        int length();
        void replace(string a, string b);
        UTF8string operator+(UTF8string &a);
        UTF8string operator*(int a);
        UTF8string operator+=(const UTF8string& rhs){
            data.append(rhs.data);
            return *this;
        }
        friend UTF8string operator!(UTF8string &a);
        friend std::ostream& operator<<(std::ostream& os, UTF8string &a);
        friend UTF8string operator+(int a,  UTF8string &other );
};
std::ostream& operator<<(std::ostream& os, UTF8string &a){
    os << a.data;
    return os;
}
UTF8string UTF8string::operator+(UTF8string &a){
    string b = data ;
    return UTF8string(b.append(a.data));

}

我的测试代码:

    cout << "test + test2: " << test + test2 << endl; // doesn't work
    cout << "test contains: " << test << endl; // works well

错误

testUTF8string.cpp:38:38: 错误:cannot bind non-const lvalue reference of type ‘UTF8string&’ to an rvalue of type ‘UTF8string’  
   38 |     cout << "test + test2: " << test + test2 << endl;  
      |                                 ~~~~~^~~~~~~

3 个答案:

答案 0 :(得分:3)

您始终使用对非const的引用。

那是个坏主意。

如果您不需要通过引用修改对象,则引用应为const

如果您引用的不是const,则临时者无法绑定到它。

您的operator+的按值返回结果是临时的。

答案 1 :(得分:1)

operator+test + test2重载的结果是临时值。非const引用不能将临时值传递给函数。

可以使用const参考进行修复:

std::ostream& operator<<(std::ostream& os, const UTF8string &a){
    os << a.data;
    return os;
}

UTF8string UTF8string::operator+(const UTF8string &a){
    string b = data ;
    return UTF8string(b.append(a.data));
}

优良作法是,在传递本意为只读的参数时始终使用const引用。

答案 2 :(得分:0)

除了解决方案之外,与Monica一起使用的@Lightness Races还建议您还可以使operator <<重载右值引用,例如:-

friend std::ostream& operator<<(std::ostream& os, const UTF8string &&a);

在移动比复制便宜的情况下,像这样过载有时会很有用。 或者由于某种原因,您希望在两种情况下采用不同的实现。

注意::对于operator <<,没有意义,因为要传递给流的数据/对象应该为const