c++oopoperator-overloadingextraction-operator

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.


Solution

  • 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";
    }