且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

找出C ++对象是否可调用

更新时间:2023-11-30 18:29:46

我认为此特征可以满足您的需求.即使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
{ };