是否可以参数化非类型模板参数?我正在尝试生成一个thunk,它根据一些运行时检查将其参数转发给两个编译时常量函数之一,以获得有希望的东西:
#include <stdlib.h>
int a(int, int, char) {
return 0;
}
int b(int, int, char) {
return 0;
}
// This doesn't work
template<typename ReturnType, typename... Params>
template<ReturnType (*first)(Params...), ReturnType (*second)(Params...)>
ReturnType coin_flip(Params... params) {
if (rand() % 2) {
return first(params...);
} else {
return second(params...);
}
}
int main() {
return coin_flip<a, b>(1, 2, '3');
}
答案 0 :(得分:2)
有一种解决方法,它使用类型模板参数(通过std::integral_constant
)和宏:
#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__)
使用示例:
std::cout << COIN_FLIP(a, b, 1, 2, '3') << std::endl;
答案 1 :(得分:0)
以下可能会有所帮助:
template<typename F, F f1, F f2, typename... Params>
auto coin_flip(Params&&... params) -> decltype(f1(std::forward<Params>(params)...)) {
if (rand() % 2) {
return f1(std::forward<Params>(params)...);
} else {
return f2(std::forward<Params>(params)...);
}
}
int main() {
return coin_flip<decltype(&a), &a, &b>(1, 2, '3');
}
答案 2 :(得分:0)
您可以将函数作为参数传递给coin_flip
(而不是模板参数):
#include <iostream>
#include <cstdlib>
#include <type_traits>
int a(int, int, char) {
std::cout << 'a';
return 0;
}
int b(int, int, char) {
std::cout << 'b';
return 0;
}
template<typename FnA, typename FnB, typename... Params>
typename std::result_of<FnA&(Params...)>::type
coin_flip(FnA a, FnB b, Params... params) {
// For testing, the condition is removed here
a(params...);
return b(params...);
}
int main() {
coin_flip(a, b, 1, 2, '3');
std::cout << '\n';
return 0;
}