我正试图把我的头围绕参数包,并需要一点帮助。
看看下面这个精心设计的例子,有没有办法将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);
}发布于 2016-02-25 17:28:15
首先,语法应该是:
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;
}https://stackoverflow.com/questions/35633638
复制相似问题