Search code examples
c++c++11operator-overloadingpointer-to-membermutators

C++ Operator>> Overloading with Mutator?


I am trying to figure out a way (if possible) to overload the >> operator to function correctly with a mutator. For example, I want to write:

myClass obj;
cin >> obj.setValue;

and have it correctly set the obj's private value using the available mutator in a single line. I know I can use a temporary variable to store the cin and set the obj value with that, but I'm wondering if there is a more concise method such as this. I'm a novice programmer so this is my futile attempt within myClass:

friend std::istream &operator>>(std::istream &in, void (myClass::*pt)(double newValue)) {
    double temp;
    in >> temp;
    pt(temp);
    return in;
}

I know I can simply overload the myClass as a whole to accept:

cin >> myClass;

but this would prevent me from setting different individual values within myClass at different times.

Thanks


Solution

  • cin >> obj.setValue or cin >> &obj.setValue are examples of invalid C++. There's no way of getting a reference/pointer to a member function of a particular instance of a class.

    What you could do is instead package the this pointer and a pointer to member function in a small struct, and overload operator>> on that instead:

    template <typename T, typename Arg>
    struct setter_t
    {
        T* _this;
        void (T::*_ptr)(Arg);
    };
    
    template <typename T, typename Arg>
    auto setter(T& x, void (T::*ptr)(Arg))
    {
        return setter_t<T, Arg>{&x, ptr};
    }
    
    template <typename T, typename Arg>
    std::istream &operator>>(std::istream &in, setter_t<T, Arg> s) 
    {
        Arg temp;
        in >> temp;
        (s._this->*s._ptr)(temp);
        return in;
    }
    

    Usage:

    myClass obj;
    std::cin >> setter(obj, &myClass::setValue);
    

    live wandbox example


    Here's a C++17 solution that doesn't unnecessarily store _ptr inside setter_t. Usage:

    std::cin >> setter<&myClass::setValue>(obj);
    

    live wandbox example