std::result_of<test(Arg const&)>
提供一个模板参数,它是一个函数类型,它引用Arg const
并返回一个test
. 所以它type
不是test
很有帮助。
请注意,正如所写,需要代码
bar b;
foo f;
b(f);
要有效实际上是 5 个要求: bar
并且foo
每个都有一个可访问的默认构造函数和析构函数,并且b(f)
是一个有效的表达式。我将只关注最后一个(这可能就是你的意思)。如果您确实是指其他部分,则可以使用标准<type_traits>
属性添加这些部分。
该函数std::declval
非常适合假装您拥有给定类型的对象,即使您没有。它永远不能被调用,所以它通常只在decltype
表达式中使用。
有两种实现 SFINAE 技巧的基本方法,基于 C++ 允许模板参数推导失败的两个地方,以丢弃失败的声明:
首先,尝试匹配一个类的偏特化:
template<typename Func, typename Arg, typename Enable = void>
struct has_call_with_arg1 : public std::false_type {};
template<typename Func, typename Arg>
struct has_call_with_arg1<Func, Arg,
decltype(std::declval<Func&>()(std::declval<Arg&>()))>
: public std::true_type {};
其次,当至少一个重载是函数模板时,重载决议。(类模板的非模板成员函数在这里不起作用,因为实例化类需要每个成员声明都有效。)
namespace has_call_with_arg_impl {
template<typename F, typename A>
std::true_type test(decltype(std::declval<F&>()(std::declval<A&>()))*);
template<typename F, typename A>
std::false_type test(...);
}
template <typename Func, typename Arg>
struct has_call_with_arg2
: public decltype(has_call_with_arg_impl::test<Func,Arg>(nullptr)) {};
演示:http: //ideone.com/KgRI8y