我正在尝试检查仿函数是否与给定的一组参数类型和给定的返回类型兼容(也就是说,给定的参数类型可以被隐含地转换为实际的参数类型,反之亦然的是返回类型).目前我使用以下代码:
template<typename T,typename R,template<typename U,typename V> class Comparer> struct check_type { enum {value = Comparer<T,R>::value}; }; template<typename T,typename Return,typename... Args> struct is_functor_compatible { struct base: public T { using T::operator(); std::false_type operator()(...)const; }; enum {value = check_type<decltype(std::declval<base>()(std::declval<Args>()...)),Return,std::is_convertible>::value}; };
check_type< T,V,Comparer>
这在大多数情况下工作得很好,但是当我测试像struct foo {int operator()()const;};这样的无参数函子时,它无法编译,因为在这种情况下,base的两个operator()很好暧昧,导致这样的事情:
error: call of '(is_functor_compatible<foo,void>::base) ()' is ambiguous note: candidates are: note: std::false_type is_functor_compatible<T,Args>::base::operator()(...) const [with T = foo,Return = void,Args = {},std::false_type = std::integral_constant<bool,false>] note: int foo::operator()() const
因此,我需要一种不同的方法来检查无参数仿函数.我尝试对一个空参数包进行is_functor_compatible的部分特化,其中我检查& T :: operator()的类型是否是无参数的成员函数,它或多或少有效.但是,当测试的仿函数有多个operator()时,这种方法显然会失败.
因此,我的问题是,是否有更好的方法来测试无参数运算符()的存在以及如何执行它.
解决方法
当我想测试给定表达式是否对某个类型有效时,我使用类似于这个的结构:
template <typename T> struct is_callable_without_parameters { private: template <typename T1> static decltype(std::declval<T1>()(),void(),0) test(int); template <typename> static void test(...); public: enum { value = !std::is_void<decltype(test<T>(0))>::value }; };