Search code examples
c++overloadingeigenoperator-keywordistream

How to overload >> operator to take a comma separated variable argument list


--Quick Before

So before anyone says this question has been answered on another post it hasn't... It was a homework question in the other post and the original question was never answered only told they were wrong.

--Question

I am trying to overload the >> operator to be able to pass in n-number of variables seperated by commas into an object like so...

Mat M = (Mat_<double>(3,3) << 1, 0, 0, 0, 1, 0, 0, 0, 1);

I am trying to reuse their usage of the comma seperated argument list but I can't seem to get it to work.

When I overload the << operator like so

void operator<< (const double& is)
{
    std::cout << "hiya " << is << std::endl;
}

and attempt to use it like so

mat << 1.0, 2.0;

only the first value is passed to the operator... The second value is never 'used' as I believe that << has a higher presidence than ,

So my question is what are they doing in libraries like eigen and openCV to be able to have this functionality. I have looked through their code to attempt to understand it but it appears to require a deeper understanding of how C++ works that I don't have and I was hoping someone here could shed some light on it.

Thanks in advance for any advice.


Solution

  • You'll have to overload the insertion operator (<<) and the comma operator (,) such that

    mat << 1.0, 2.0;
    

    is translated as:

    mat.operator<<(1.0).operator,(2.0);
    

    or

    operator,(operator<<(mat, 1.0), 2.0);
    

    Here's a demonstrative program that illustrates the idea without doing anything useful.

    struct Foo
    {
    };
    
    Foo& operator<<(Foo& f, double)
    {
      std::cout << "In operator<<(Foo& f, double)\n";
       return f;
    }
    
    Foo& operator,(Foo& f, double)
    {
       std::cout << "In operator,(Foo& f, double)\n";
       return f;
    }
    
    int main()
    {
       Foo f;
       f << 10, 20, 30;
    }
    

    and its output

    In operator<<(Foo& f, double)
    In operator,(Foo& f, double)
    In operator,(Foo& f, double)