#include <functional>
#include <iostream>
#include <cassert>

int    foo(double d) { return d; }

double bar(double d) { return 2*d; }

struct Result {
	union {
		int    i_res;
		double d_res;
	};
	enum { IS_INT, IS_DOUBLE } u_tag;
	
	Result(Result const&) = default;
	Result(int i)  : i_res{i}, u_tag{IS_INT} {}
	Result(double d) : d_res{d}, u_tag{IS_DOUBLE} {}
	
	Result& operator=(Result const&) = default;
	auto& operator=(int i)
	{ i_res = i; u_tag = IS_INT;    return *this; }
	auto& operator=(double d)
	{ d_res = d; u_tag = IS_DOUBLE; return *this; }
};

int main() {
	std::function<Result(double)> cb;
	
	cb = foo;
	auto r = cb(1.0);
	assert(r.u_tag == Result::IS_INT);
	std::cout << r.i_res << '\n';
	
	cb = bar;
	r = cb(2.0);
	assert(r.u_tag == Result::IS_DOUBLE); 
	std::cout << r.d_res << '\n';

	return 0;
}