Zaif Senpai
Zaif Senpai

Reputation: 91

How to use extraction operator to get multiple values from method of a class in C++?

Like we use in cin:

cin >> a >> b;

to get multiple values from input stream and insert them to multiple variables. How can we implement this method in our own class? To get multiple values from it. I tried this as found here:

#include <iostream>
using namespace std;

class example {
    friend istream& operator>> (istream& is, example& exam);
    private:
        int my = 2;
        int my2 = 4;
};

istream& operator>> (istream& is, example& exam) {
    is >> exam.my >> exam.my2;
    return is;  
}

int main() {
    example abc;
    int s, t;

    abc >> s >> t;
    cout << s << t;
}

But getting error "no match for operator>> (operand types are 'example' and 'int')"

PS: I know the alternate ways but I want to know this specific way of doing this, Thanks.

Upvotes: 0

Views: 1129

Answers (2)

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 153840

The insertion operator you defined works with std::istream as a source rather than you own class. Although I think your objective is ill-advised, you can create similar operators for your class. You'll need some entity with a suitable state as chained operators should extract different values.

I wouldn't use this for any sort of production set up but it certainly can be done:

#include <iostream>
#include <tuple>
using namespace std;

template <int Index, typename... T>
class extractor {
    std::tuple<T const&...> values;
public:
    extractor(std::tuple<T const&...> values): values(values) {}
    template <typename A>
    extractor<Index + 1, T...> operator>> (A& arg) {
        arg = std::get<Index>(values);
        return extractor<Index + 1, T...>{ values };
    }
};

template <typename... T>
extractor<0, T...> make_extractor(T const&... values) {
    return extractor<0, T...>(std::tie(values...));
}

class example {
private:
    int my = 2;
    int my2 = 4;
    double my3 = 3.14;
public:
    template <typename A>
    extractor<0, int, double> operator>> (A& arg) {
        arg = my;
        return make_extractor(this->my2, this->my3);
    }
};

int main() {
    example abc;
    int s, t;
    double x;

    abc >> s >> t >> x;
    cout << s << " " << t << " " << x << "\n";
}

Upvotes: 1

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385204

You want to extract data from an example into an int. Instead, you wrote code to extract data from an istream into an example. That's why the right function cannot be found: you did not write one.

If you really wish to allow abc >> s >> t to work, you're going to have to define an operator>>(example&, int&) and add stream/cursor semantics to your class, to keep track at each step of what's been extracted so far. That really sounds like more trouble than it's worth.

Upvotes: 1

Related Questions