我需要弄清楚模板参数是否是具有非无效返回值的可调用对象。

我定义了以下内容:

template<class T, class U = T>
struct is_callable
{
    constexpr static const bool val = false;
};

template<class T>
struct is_callable<T, std::result_of_t<T()>>
{
    constexpr static const bool val = true;
};

template<class T>
constexpr bool is_func = is_callable<T>::val;

但是以下变量都是false
auto lambda = []() {return 3.0; };

auto intIsFunc = is_func<int>; //false -- ok
auto functionIsFunc = is_func<std::function<int()>>; //false -- wrong
auto lambdaIsFunc = is_func<decltype(lambda)>; //false -- wrong
  • 代码有什么问题?
  • 如何改进is_func不仅在可调用对象上返回true,而且还可以使用可构造的返回类型(在std::is_constructible_v<>处使用)返回ojit_code?
  • 最佳答案

    使用enable_if

    template <typename T, typename = void>
    struct is_callable_non_void_return : public std::false_type {};
    
    template <typename T>
    struct is_callable_non_void_return<
        T,
        std::enable_if_t<!std::is_same_v<void, std::result_of_t<T()>>>>
        : public std::true_type {};
    

    这是因为SFINAE而起作用:替换失败不是错误。

    编译器会将第二个is_callable_non_void_return视作第一个enable_if的特殊化,并尝试通过实例化result_of_t来匹配模板:首先是is_same_v,然后是ojit_code。如果中的任何一个失败,那么替换失败就会发生,编译器会退回到一般情况。

    07-25 21:29