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

时间:2015-12-06 05:01:09

标签: c++ templates c++11

我想检查模板中提供的类型是否有获得size_t类型的methond并返回算术类型。对于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);
};

但所有算术类型看起来如何?

1 个答案:

答案 0 :(得分:2)

您可以使用现代黑魔法来实施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内的东西有效时,部分特化更好(更专业)。否则使用一般默认值。在这里,我将所有T分开,以便使用单个T::function_name参数调用size_t。之后,我会对该呼叫的返回类型进行额外的is_arithmetic检查。您可能会发现此检查仍然有点松散:function_name(float)会将其传递,因为size_t值可以隐式转换为float。由于您知道function_name存在并且检查它不会触发硬编译错误,因此您可以轻松地使用其他检查进行部分特化。