#include <iostream>

struct X
{
	template <typename F>
	auto accept(F && f)
	{
		return [this, &f](auto &&... args) {
			return f(this, std::forward<decltype(args)>(args)...); };
	}

	virtual void foo() const { std::cout << "base\n"; }
};

struct Y : X
{
	void foo() const override { std::cout << "derived\n"; }
};


int main()
{
	Y y;
	X * p = &y;
	
	(p->*(&X::foo))();
	
	p->accept([](X * that){that->X::foo();});
}