Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if type provides function with arithmetic type

I want to check if type provided in template has methond which gets size_t type and return arithmetic type. For int it looks like

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);
};

but how it looks like for all arithmetic types?

like image 289
platynamen Avatar asked Feb 12 '26 02:02

platynamen


1 Answers

You can use modern black magic for implementing has_something checks:

// 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>()))> {
};

The idea here is that partial specialization is better (more specialized) when stuff inside its void_t is valid. Otherwise general default is used. Here I split all T's by possibility to invoke T::function_name with a single size_t parameter. After that I do additional is_arithmetic check on the return type of that call. You might find this check a bit loose still: a function_name(float) will pass it, because size_t value can be implicitly converted to a float. You may stuff partial specialization with additional checks easily since you know that function_name exists and checks around it won't trigger hard compilation error.

like image 64
Constantin Baranov Avatar answered Feb 13 '26 16:02

Constantin Baranov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!