找出一个C ++对象是否可调用 [英] find out if a C++ object is callable

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

问题描述

可以写一个类型trait,例如 is_callable ,它告诉对象是否有 $ c> defined?
如果事先知道调用操作符的参数,但很容易,但在一般情况下不是这样。
如果且只有在定义了至少一个重载的调用操作符时,我希望trait返回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 只有真正的函数而不是函子,我正在寻找一个更通用的解决方案。

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

推荐答案

我认为这个特质是你想要的。它检测运算符()与任何种类的签名,即使它是重载的,如果它的模板化:

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);
};

Live演示

原则是基于成员检测器成语。事实上,如果你传递一个非类型的类型,它将无法编译,但这不应该是很难修复,我刚刚省略为了简洁。你也可以扩展它来为函数报告true。

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.

当然,它不会给你任何关于 ()无论如何,但我相信这不是你要求的,对吗?

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天全站免登陆