Перегрузка оператора c ++ + = работает, но << не работает - PullRequest
6 голосов
/ 28 апреля 2019

Я ожидал, что + = и << будут работать одинаково, но << как-то не работает. </p>

вот мой код:

#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 ]

7 голосов
/ 28 апреля 2019

Это: {10, 20} - это список фигурных скобок. Это , а не выражение . Как таковой, он может появиться только в определенных частях грамматики C ++ .

Например, braced-init-lists могут появляться после typename, что означает, что они инициализируют prvalue этого типа. Они могут появляться в качестве аргумента функции. И (среди нескольких других) они могут появляться в правой части оператора присваивания.

Обратите внимание, что += является оператором присваивания.

<< является не одним из этих определенных мест. Таким образом, голый фигурный скобочный список инициализации не может появляться с обеих сторон выражения <<. Это не зависит от того факта, что выражение << будет преобразовано в вызов operator<<, и, таким образом, список фигурных скобок init можно считать аргументом функции. Грамматика C ++ просто не позволяет появиться в ней фигурному списку инициализации, поэтому компилятор никогда не заходит достаточно далеко, чтобы даже пытается разрешить перегрузку, чтобы выяснить, какую функцию вызывать.

0 голосов
/ 28 апреля 2019

Оператору << нужен ostream на левой стороне.Вот версия .Net того, что вы должны сделать для потоковой передачи объекта Date на cout: </p>

#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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...