Как реализовать оператор извлечения в классе?

У меня есть класс, который читает части двоичного файла в переменные разных типов.

class Foo {
public:
    size_t getSizeT();
    float getFloat();
    std::string getString();
private:
    std::ifstream stream;
};

Теперь я хотел бы реализовать оператор извлечения потока, как описано в этом ответе.

class Foo {
public:
    Foo &operator>>(Foo &foo, size_t &value);
    Foo &operator>>(Foo &foo, float &value);
    Foo &operator>>(Foo &foo, std::string &value);
private:
    std::ifstream stream;
};

Код не компилируется с этим сообщением об ошибке: error C2804: binary 'operator >>' has too many parameters, Как правильно переопределить оператор извлечения потока? Следует различать типы и быть цепным.

2 ответа

Решение

В качестве свободной функции подпись оператора должна быть:

Foo& operator >>(Foo& foo, size_t& value);

Как функция-член (ваш случай), она должна быть:

Foo& operator >>(size_t& value);

Если источником данных является экземпляр вашего класса, то у вас есть два способа написания функции оператора ввода: либо как отдельная глобальная функция, принимающая два аргумента, экземпляр вашего класса и целевой объект. Или вы пишете это как функцию-член вашего класса, и тогда он принимает только один аргумент, который является местом назначения.

Таким образом, для глобальной функции вы пишете, например,

class Foo { ... };

Foo& operator>>(Foo& foo, int& i)
{
    // Get an integer and writes to `i` here
    return foo;
}

Для функции-члена вы пишете, например,

class Foo
{
public:
    ...

    Foo& operator>>(int& i)
    {
        // Get an integer and writes to `i` here
        return *this;
    }
};

Причина, по которой я думаю, что вы написали неправильный оператор, заключается в том, что вы можете написать первую версию, используя глобальные функции, в качестве функции- друга, встроенной в класс, и вы уже видели это, прежде чем ошибиться между разницей между функцией-другом и функцией-членом.

Вы используете функции друзей, как

class Foo
{
public:
    ...

    // Notice the keyword `friend` 
    friend Foo& operator>>(Foo& foo, int& i)
    {
        // Get an integer and writes to `i` here
        return foo;
    }
};

Разница между функцией-членом и функцией-другом невелика, но очень важна.

Другие вопросы по тегам