Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Is it possible to overload an operator with a function as a parameter?

I just discovered operator overloading and I am just chuffed to bits with it. In testing its uses, I came across one case that I can’t seem to make work, and I cannot find the appropriate resources to resolve.

I am trying to overload an operator which would take a function as an argument. My goal is to create a structure that can execute any function given to it (within reason, like submit commands that would follow the same general structure). Passing a struct or class would not work in this case because the internal operation of the operator would contain an execute function. If the struct or class does not have a matching member function, then the operation would not work. Such as in the following case:

struct s_test1 {
     void funcA() {}
}
struct s_test2 {
     void funcB() {}
}
struct s_doer {
     friend void operator<<(auto, auto& s_input){
          s_input.funcA(); // would fail for s_test2
          s_input.funcB(); // would fail for s_test1
     }
}

Ultimately, I would like to create something like this pseudo-code:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

void func0(int& storage) { storage = 0; }
void func1(int& storage) { storage = 1; }
void func2(int& storage) { storage = 2; }

void alt_func(int& storage, int alt) { storage = alt; }

struct s_doer {
     friend void operator<<(auto, void(*func)()){
          int storage;
          func(storage);
          cout << storage << endl; // to check if it worked, idk
     }
}

int main() {
    s_doer{} << func0();
    s_doer{} << func1();
    s_doer{} << alt_func(); // alternatively 's_doer << alt_func(), 0' where '0' is the alt parameter of 'alt_func'
}

Here is my current implementation attempt:

struct s_doer {
    friend void operator<<(auto, void (*func)()) {
        std::cout << "test" << std:endl;
        func();
        std::cout << "test" << std::endl;
    }
};
struct s_informer {
    s_informer(int n) {
        info = n;
    }
    void inform() {
        std::cout << info << std::endl;
    }
private:
    int info;
    friend void operator<<(auto, const void (*func)());
};

s_informer informer(2);

int main() {
    s_doer{} << informer.inform();
}

I can’t seem to get passed the no operator "<<" matches these operands error.

Some of my other attempts have been:

friend void operator<<(auto, std::function<void()> func) {...}

template<typename input>
using Func = void(*)(input in);
friend void operator<<(auto, Func func) {...}

typedef void (*Func)(int n);
friend void operator<<(auto, Func func) {...}

Is overloading an operator with a functional input possible? Is it possible to specify parameters during overloading for the function as well?

How would it be done?

>Solution :

informer.inform() calls the function immediately, while you want to delay the call until operator<<.

You can pass a lambda that calls it, then call it in operator<<.

#include <functional>
#include <iostream>

struct s_doer
{
    template <typename F>
    friend void operator<<(s_doer, F &&func)
    {
        std::cout << "test\n";
        std::forward<F>(func)();
        std::cout << "test\n";
    }
};

struct s_informer
{
    s_informer(int n)
    {
        info = n;
    }
    void inform()
    {
        std::cout << info << std::endl;
    }

  private:
    int info;
};

s_informer informer(2);

int main()
{
    s_doer{} << []{informer.inform();};
}

Notice that I’ve changed the second parameter of operator<< to be templated, otherwise you won’t be able to accept capturing lambdas (which is good for generality, though this specific lambda is not capturing).

I also changed the first parameter from auto to s_doer. The former, while clever, can have unintended side effects:

template <typename> struct A {};

int main()
{
    A<s_doer>{} << []{informer.inform();}; // This actually compiles! But you don't want it to.
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading