0

I want to overload the operator << for streams so that when I call it with a function that takes a stream it will call the function (to optimize string concatenation). However, it doesn't seem to be working for member functions.

#include <iostream>

std::ostream& operator<< (std::ostream& s, void(*f)(std::ostream&)) {
    f(s);
    return s;
}

void hello (std::ostream& s) {
    s << "Hello, World!";
}

class Foo {
public:
    void hello (std::ostream& s) {
        s << "Hello from class.";
    }
};

int main(int argc, char const *argv[])
{
    // This works
    std::cout << hello << std::endl;

    // This doesn't
    Foo o;
    std::cout << o.hello << std::endl;

    return 0;
}

This code fails to compile with the error "error: invalid use of non-static member function ‘void Foo::hello(std::ostream&)’". After some searching, I discovered that I needed a function which takes a pointer to member in the form void(Foo::*)(), however adding the following to the top of the code did not get the code to compile.

template <typename T>
std::ostream& operator<< (std::ostream& s, void(T::*f)(std::ostream&)) {
    f(s);
    return s;
}

Is there any way to make this work?

RenanB
  • 105
  • 1
  • 9
  • 1
    TL;DR: To call a non-static member function (say `T::*f`) you need an instance of the object (i.e. an instance of T). – Max Langhof May 09 '19 at 15:08
  • The correct way to form the member function pointer would be `&Foo::hello`; `o.hello`, `&o.hello` and `Foo::hello` are all wrong. That doesn't really solve the problem, and I don't think you'll find a generic way to do this "stream the member function" style. But there might be interesting answers if you ask about the wider problem you're trying to solve! – Max Langhof May 09 '19 at 15:16

0 Answers0