There is a workaround which uses type template parameters (via std::integral_constant
) and macros:
#include <type_traits>
template <typename, typename>
struct coin_flip;
template
<
typename ReturnType,
typename... Params,
ReturnType (*first)(Params...),
ReturnType (*second)(Params...)
>
struct coin_flip
<
std::integral_constant<ReturnType (*)(Params...), first>,
std::integral_constant<ReturnType (*)(Params...), second>
>
{
static
ReturnType call(Params&&... params) {
if (rand() % 2) {
return first(std::forward<Params>(params)...);
} else {
return second(std::forward<Params>(params)...);
}
}
};
#define FUNCTION_CONSTANT(f) std::integral_constant<decltype(&f), f>
#define COIN_FLIP(first, second, ...) \
coin_flip<FUNCTION_CONSTANT(first), FUNCTION_CONSTANT(second)>::call(__VA_ARGS__)
Example of using:
std::cout << COIN_FLIP(a, b, 1, 2, '3') << std::endl;