我试图绕过参数包并需要一些帮助。
看看下面的人为举例,有没有办法将Args与T进行比较,只允许bar()
编译才能匹配?例如,如果我创建Task<void(int, char, float)>
我希望bar(float, char, float)
不要编译,而bar(int, char, float)
编译就好了。这甚至可行吗?
template <typename... Types>
struct foo {};
template<typename T>
struct Task;
template<typename R, typename...Args>
struct Task<R(Args...)>
{
template<typename... T>
std::enable_if<is_same<T, Args>
void bar(T... args)
{
//do something here
}
};
int main()
{
Task<int(int)> task;
int a = 0;
float b = 1.0;
bool c = false;
//compiles
task.bar(a);
//none of these should compile
task.bar(b);
task.bar(c);
task.bar(a, b);
task.bar(a, b, c);
}
答案 0 :(得分:0)
首先,语法应该是:
template<typename R, typename...Args>
struct Task<R(Args...)>
{
template<typename... T>
std::enable_if<is_same<tuple<T...>, tuple<Args...> >::value > bar(T... args)
{
//do something here
}
};
由于SFINAE,编译很好:例如,在尝试实例化bar(bool)
时,第一个实例化失败了bool类型,但在执行参数转换为int时存在实例化。
要获得所需的效果,您需要在实例化模板后进行硬类型检查:
#include <type_traits>
#include <tuple>
template<typename T>
struct Task;
template<typename R, typename... Args>
struct Task<R(Args...)>
{
template<typename... OtherArgs>
void bar(OtherArgs... otherArgs)
{
static_assert(
std::is_same<std::tuple<Args...>, std::tuple<OtherArgs...> >::value,
"Use same args types !"
);
// Do something
}
};
int main()
{
Task<int(int)> task;
// Compiles fine
task.bar(1);
// Fails to compile
task.bar('u');
task.bar(0ul);
return 0;
}