如何检查成员操作符(类型)
how check for member operator(type)?
假设我有类型bar
和foo
。我怎样才能构造一个模板类has_call_with_arg<>
,使has_call_with_arg<bar,foo>::value
当且仅当
bar b;
foo f;
b(f);
编译吗?我查看了各种相关问题(包括上面提到的)并尝试
template<typename Func, typename Arg>
class has_call_with_arg
{
struct bad {};
struct test : Func
{
template<typename C>
bad operator()(C const&r);
};
public:
static const bool value =
!std::is_same<bad, typename std::result_of<test(Arg const&)>::type >::value;
};
,但没有工作(没有检测到正确的匹配)。怎么了?
template<typename sig, typename functor> struct is_callable;
template<typename Ret, typename... Arg, typename functor>
struct is_callable<Ret(Arg...), functor> { // partial spec
private:
struct no {};
public:
template<typename U> static auto f(std::nullptr_t) -> decltype(std::declval<U>()(std::declval<Arg>()...));
template<typename U> static no f(...);
static const int value = std::is_convertible<decltype(f<functor>(nullptr)), Ret>::value;
};
我为我的教程创建了这个内容,它解释了这个特性的构造(首先是非可变形式)。
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
表达式中使用。
首先,尝试匹配类的部分专门化:
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
相关文章:
- 带引用类成员的赋值操作符
- 通过自增操作符访问类成员
- 用于具有const数据成员的类的move和右值赋值操作符
- 使用constness修改重载成员操作符
- 私有内部成员的操作符重载
- 在操作符[]前解引用成员指针
- 解引用操作符(*)作为类的成员函数重载时是如何工作的?
- c++操作符=类成员中有互斥对象
- c++的另一个类成员和重载操作符
- 双(?)定义模板成员操作符
- 为具有引用成员变量的类创建赋值操作符
- 在复制赋值操作符中赋值基类成员
- 从模板化的类赋值操作符访问私有成员变量
- 在静态成员数组定义中对自身使用sizeof操作符
- 为什么c++中的成员函数在对象名后用点操作符访问?
- 从成员函数调用重载操作符(静态)
- 如何检查成员操作符(类型)
- 指向成员操作符的指针
- 用int成员实现哪些操作符
- 如何处理赋值操作符和复制构造函数中的引用数据成员