如何检查类型是否为函数提供算术类型

How to check if type provides function with arithmetic type

本文关键字:类型 函数 是否 检查 何检查      更新时间:2023-10-16

我想检查模板中提供的类型是否有获取size_t类型和返回算术类型的方法。对于int,它看起来像

template <typename U>
struct has<U> {
    template <typename T, T>
    struct helper;
    template <typename T>
    static std::uint8_t check(helper<int (*)(size_t), &T::function_name>*);
    template <typename T>
    static std::uint16_t check(...);
    static constexpr bool value = sizeof(check<U>(0)) == sizeof(std::uint8_t);
};

但是对于所有的算术类型,它看起来是什么样子的呢?

您可以使用现代黑魔法来实现has_something检查:

// Stolen from C++17 std::
template<typename...> using void_t = void;
template<typename T, typename = void_t<>>
struct has: std::integral_constant<bool, false> {
};
template<typename T>
struct has<T, void_t<decltype(T::function_name(std::declval<std::size_t>()))>>:
    std::is_arithmetic<decltype(T::function_name(std::declval<std::size_t>()))> {
};

这里的想法是,当void_t中的内容有效时,部分专业化更好(更专业化)。否则将使用常规默认值。在这里,我通过使用单个size_t参数调用T::function_name的可能性来划分所有T。之后,我对该调用的返回类型进行额外的is_arithmetic检查。您可能会发现这个检查仍然有点松散:function_name(float)会通过它,因为size_t的值可以隐式转换为float。您可以很容易地用额外的检查来填充部分专门化,因为您知道function_name存在,并且围绕它的检查不会触发硬编译错误。