【发布时间】:2014-05-17 21:51:15
【问题描述】:
我想创建一个编译类型函数,给定任何可调用对象f(函数、lambda 表达式、函数对象...)和类型T,如果f,则计算结果为真可以使用 T 类型的参数调用,如果不能调用,则为 false。
例子:
void f1(int) { ... }
void f2(const std::string&) { ... }
assert( is_callable_with<int>(f1));
assert(!is_callable_with<int>(f2));
我认为巧妙地使用 SFINAE 规则可以实现这一目标。可能是这样的:
template<typename T, typename F>
constexpr bool is_callable_with(F&&, typename std::result_of<F(T)>::type* = nullptr) {
return true;
}
template<typename T, typename F>
constexpr bool is_callable_with(F&&) {
return false;
}
但这不起作用,因为如果F 可以用T 调用,则两个重载都参与重载解析,并且存在歧义。我想重写它,所以在积极的情况下,第一个重载将被重载决议选择而不是第二个重载。不过,我不确定我是否走在正确的轨道上。
【问题讨论】:
-
好吧,你必须让一个重载成为参数的更差匹配。例如,您可以在第二个重载中添加一个省略号,并通过添加一个附加参数
nullptr(调用is_callable_with<T>(f, nullptr))来添加一个选择这两个重载之一的函数。 -
我是唯一一个在计算开始在他的 C++ 项目中使用 Concepts 的日子的人吗? :P
标签: c++ templates c++11 template-meta-programming