找出C ++对象是否可调用 [英] Find out whether a C++ object is callable

查看:52
本文介绍了找出C ++对象是否可调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以写一个类型特征,例如is_callable<T>,它告诉对象是否定义了operator()? 如果事先知道调用运算符的参数是很容易的,但通常情况下是不知道的. 我希望当且仅当至少定义了一个重载的调用运算符时,特征才能返回true.

Is it possible to write a type trait, say is_callable<T> which tells if an object has an operator() defined? It is easy if the arguments to the call operator are known in advance, but not in the general case. I want the trait to return true if and only if there is at least one overloaded call operator defined.

该问题与之相关并且具有很好的答案,但是它不适用于所有类型(仅适用于int可转换类型).另外,std::is_function可以工作,但只能在适当的C ++函数上使用,而不能在函子上使用.我正在寻找更通用的解决方案.

This question is related and has a good answer, but it doesn't work on all types (only on int-convertible types). Also, std::is_function works, but only on proper C++ functions, not on functors. I'm looking for a more general solution.

推荐答案

我认为此特征可以满足您的需求.即使operator()已过载并且已被模板化,它也可以检测到具有任何签名的operator():

I think this trait does what you want. It detects operator() with any kind of signature even if it's overloaded and also if it's templatized:

template<typename T>
struct is_callable {
private:
    typedef char(&yes)[1];
    typedef char(&no)[2];

    struct Fallback { void operator()(); };
    struct Derived : T, Fallback { };

    template<typename U, U> struct Check;

    template<typename>
    static yes test(...);

    template<typename C>
    static no test(Check<void (Fallback::*)(), &C::operator()>*);

public:
    static const bool value = sizeof(test<Derived>(0)) == sizeof(yes);
};

该原理基于成员检测器用法.照原样,如果您将其传递为非类类型,它将无法编译,但这并不难解决,为简洁起见,我将其省略.您还可以扩展它以对功能报告为真.

The principle is based on Member Detector idiom. As it is, it will fail to compile if you pass it a non-class type, but that shouldn't be hard to fix, I just left it out for brevity. You can also extend it to report true for functions.

当然,它不会给您任何有关operator()签名的信息,但是我相信这不是您要的,对吧?

Of course it doesn't give you any info about the signature(s) of operator() whatsoever, but I believe that's not what you asked for, right?

编辑 Klaim :

它非常简单,可以使它与非类类型一起工作(返回false).如果将上述类重命名为is_callable_impl,则可以编写此代码,例如:

It's simple enough to make it work (return false) with non-class types. If you rename the above class to is_callable_impl, you can write this, for example:

template<typename T>
struct is_callable
    : std::conditional<
        std::is_class<T>::value,
        is_callable_impl<T>,
        std::false_type
    >::type
{ };

这篇关于找出C ++对象是否可调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆