我需要弄清楚模板参数是否是具有非无效返回值的可调用对象。
我定义了以下内容:
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
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。如果中的任何一个失败,那么替换失败就会发生,编译器会退回到一般情况。