C ++运算符重载+ =可以,但是<<不起作用

时间:2019-04-28 03:52:40

标签: c++ oop operator-overloading

我希望+ =和<<可以相同,但是<<不能正常工作。

这是我的代码:

#include <iostream>

using namespace std;

struct Pos{
    int x;
    int y;

    void operator+=(Pos vel){
        x += vel.x;
        y += vel.y;
    }
};

struct Obj{
    string name;
    Pos pos;

    void info(){
        cout << name << endl;
        cout << pos.x << ", " << pos.y << endl;
        cout << endl;
    }
    void operator<<(Pos vel){
        pos += vel;
    }
    void operator+=(Pos vel){
        pos += vel;
    }
};


int main(){
    Pos p{10, 20};
    Obj car{"Car", p};
    Obj truck{"Big truck", {40, 20}};

    car.info();
    truck.info();

    //doesn't work
    car << {0, 10};
    //works
    car += {5, 10};
    //works
    car << Pos{0, 10};
    //works
    car += Pos{5, 10};

    car.info();
} 

大多数都可以,但是 car << {0, 10};

它显示:

[Error] expected primary-expression before '{' token

我想知道+=<<之间有什么区别,以及为什么使用构造函数会起作用。

我在这里想念什么?

2 个答案:

答案 0 :(得分:7)

此:{10, 20}是一个括号初始化列表。它不是表达式。因此,它只能显示in specific pieces of C++ grammar

例如,括号初始列表可以出现在类型名称之后,这意味着它们会初始化该类型的prvalue。它们可以作为函数的参数出现。并且(在其他几个对象中)它们可以出现在赋值运算符的右侧。

请注意,+=是赋值运算符。

<<不是这些特定位置之一。因此,赤裸的括号初始列表不能出现在<<表达式的任何一侧。这与<<表达式将转换为对operator<<的调用无关,因此braced-init-list可以视为函数参数。 C ++语法根本不允许在其中出现括号启动列表,因此编译器永远无法达到甚至尝试 重载解析以找出要调用的函数的目的。

答案 1 :(得分:-1)

<<运算符需要在lef侧有一个ostream。这是将Date对象流式传输到“ cout”所需要执行的.Net版本:

#include <iostream>
using namespace std;

class Date
{
    int mo, da, yr;
public:
    Date(int m, int d, int y)
    {
        mo = m; da = d; yr = y;
    }
    friend ostream& operator<<(ostream& os, const Date& dt);
};

ostream& operator<<(ostream& os, const Date& dt)
{
    os << dt.mo << '/' << dt.da << '/' << dt.yr;
    return os;
}

int main()
{
    Date dt(5, 6, 92);
    cout << dt;
}