2

Want to extend base_is_char_array for any size character array.

Open to an entirely different solution than using is_base_of. But I am constrained to the standard library for reasons far outside my control.

Outside of something gross that iterates to a fixed maximum array size, I'm out of ideas.

#include <array>
#include <iostream>

template< class Derived > auto base_is_char_array(){
    return std::is_base_of<std::array<char, 10>, Derived>::value;
}

int main() {
    class tester : std::array<char, 10>{};
    std::cout << base_is_char_array<tester>() << std::endl;
    std::cout << base_is_char_array<int>() << std::endl;
}
xskxzr
  • 12,442
  • 12
  • 37
  • 77
Evan
  • 2,441
  • 23
  • 36
  • 2
    I feel like if you're inheriting from std::array, you've already made some kind of mistake most of the time. It certainly shouldn't be common enough to want to ask this question. – Nicol Bolas Feb 13 '21 at 00:42
  • maybe this could help https://stackoverflow.com/questions/22592419/checking-if-a-class-inherits-from-any-template-instantiation-of-a-template – Alberto Sinigaglia Feb 13 '21 at 00:56

1 Answers1

3

cppreference gives a possible implementation of std::is_base_of. You can use the same technique to implement your base_is_char_array:

namespace details {
    template <std::size_t N>
    std::true_type  test_ptr_convertible_to_char_array(const volatile std::array<char, N>*);
    std::false_type test_ptr_convertible_to_char_array(const volatile void*);
 
    template <typename>
    auto test_base_is_char_array(...) -> std::true_type;
    template <typename D>
    auto test_base_is_char_array(int) ->
        decltype(test_ptr_convertible_to_char_array(static_cast<D*>(nullptr)));
}
 
template <typename Derived>
struct base_is_char_array :
    std::integral_constant<
        bool,
        std::is_class<Derived>::value &&
        decltype(details::test_base_is_char_array<Derived>(0))::value
    > { };
xskxzr
  • 12,442
  • 12
  • 37
  • 77