如何为模板化operator()编写最佳的is_callable特性 [英] How to write the best possible is_callable trait for templated operator()

查看:81
本文介绍了如何为模板化operator()编写最佳的is_callable特性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我具有如下定义的is_callable特性:

I have is_callable trait defined like this:

#ifndef IS_CALLABLE_HPP
#define IS_CALLABLE_HPP

#include <type_traits>

namespace is_callable_detail
{
    struct no   {};
    struct yes  { no x[2]; };

    template<bool CallableArgs, typename Callable, typename ReturnType, typename ...Args>
    struct check_return
    {
        static const bool value = std::is_convertible<decltype(std::declval<Callable>()(std::declval<Args>()...)), ReturnType>::value;
    };

    template<typename Callable, typename ReturnType, typename ...Args>
    struct check_return<false, Callable, ReturnType, Args...>
    {
        static const bool value = false;
    };
}

template<typename Callable, typename Function>
struct is_callable;

template<typename Callable, typename ReturnType, typename ...Args>
struct is_callable<Callable, ReturnType(Args...)>
{
    private:
        template<typename T>
        static is_callable_detail::yes check(decltype(std::declval<T>()(std::declval<Args>()...)) *);
        template<typename T>
        static is_callable_detail::no  check(...);

        static const bool value_args = sizeof(check<Callable>(nullptr)) == sizeof(is_callable_detail::yes);
        static const bool value_return = is_callable_detail::check_return<value_args, Callable, ReturnType, Args...>::value;
    public:
        static const bool value = value_args && value_return;
};

#endif // IS_CALLABLE_HPP

我的问题是如何检测模板运算符()没有参数,只返回类型T

My question is how to detect templated operator() which doesn't have arguments and has only return type T

template<typename T>
T operator()()
{
  // ...
}

template<typename T, typename U>
auto operator()() -> decltype(std::declval<T>() + std::declval<U>())
{
  // ...
}

我知道这种情况很少见,但我想问问有没有办法检测没有参数且带有一个或多个模板参数。

I know that this situations are rare, but I wanted to ask is there any way to detect presence of templated operator() with no arguments and with one or more template arguments.

推荐答案

如果您事先知道 operator()不会过载,您可以尝试获取其地址。如果 operator() 可能重载,则结果为正将意味着存在 operator()存在,但结果为负将意味着不存在 operator(),或者至少存在两个重载。

If you know in advance operator() is not going to be overloaded, you can try to take its address. If operator() is possibly overloaded, then a positive result would mean that there is an operator() present but a negative result would mean that either no operator() is present, or at least two overloads are.

请注意,模板将(如预期的那样)带来 operator()的一些重载。但是,如果您知道未默认设置的模板参数的数量,则可以尝试使用 operator()< T> 的地址(对于某些类型的 T 希望不会触发SFINAE)。

Notice that a template will (as expected) bring several overloads of operator(). However, if you do know the number of template parameters that are not defaulted you can try taking the address of operator()<T> (for some type T that hopefully won't trigger SFINAE).

最后一点,我建议不用花太多时间去检查函子(或出于相同原因的成员函数)而又不知道要传递什么参数,就像您已经拥有的那样。 C ++ 11使编写和使用在表达式级别起作用的通用代码变得非常容易。

As a final note, I'd suggest not trying to spend too much time trying to inspect functors (or member functions, for the same reasons) without knowing what arguments to pass, just like what you already have. C++11 makes it very easy to write and use generic code that functions at the expression level.

这篇关于如何为模板化operator()编写最佳的is_callable特性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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