Consider the following code in C++17:
#include <iostream>
#include <functional>
struct base
{
base() {std::cout << "base::base" << std::endl;}
virtual ~base() {std::cout << "base::~base" << std::endl;}
virtual void operator()() {std::cout << "base::operator()" << std::endl;}
};
struct derived1: base
{
derived1() {std::cout << "derived1::derived1" << std::endl;}
virtual ~derived1() {std::cout << "derived1::~derived1" << std::endl;}
virtual void operator()() {std::cout << "derived1::operator()" << std::endl;}
};
struct derived2: base
{
derived2() {std::cout << "derived2::derived2" << std::endl;}
virtual ~derived2() {std::cout << "derived2::~derived2" << std::endl;}
virtual void operator()() {std::cout << "derived2::operator()" << std::endl;}
};
int main(int argc, char* argv[])
{
base* ptr1 = new derived1();
base* ptr2 = new derived2();
std::function f1(*ptr1);
std::function f2(*ptr2);
std::invoke(*ptr1); // calls derived1::operator()
std::invoke(*ptr2); // calls derived2::operator()
std::invoke(f1); // calls base::operator()
std::invoke(f2); // calls base::operator()
delete ptr1;
delete ptr2;
return 0;
}
std::function
does not seem to do the right thing with virtual functions. Would there be any way to make std::invoke(*ptrN)
and std::invoke(fN)
behave the same way? Or would there be any way to create a new function wrapper that would deal with virtual functions?