Using std :: extent on std :: array

I have a boilerplate function and I want static_assertit to be three in size. This code illustrates what I am trying to do but does not work:

template < typename T >
void foo( T& param )
{
    // This line is the one that I need to figure out how to write
    static_assert( 3 == std::extent< T >::value, "param must have a size of 3" );
}

int main( void )
{
    int cArray[3];
    std::array< int, 3 > stdArray;

    foo( cArray );
    foo( stdArray );
}
+3
source share
4 answers

It is based on iavr solution.

template < typename T >
void foo( T& param )
{
    static_assert( 3 == ( std::is_array< T >::value ? std::extent< T >::value : std::tuple_size< T >::value ), "param must have a size of 3" );
}
+2
source

std::extentdefined for inline arrays. std::arrayUse instead std::tuple_size. I don't know some trait that works on both, but it's easy to write:

template<typename T>
struct array_size : std::extent<T> { };

template<typename T, size_t N>
struct array_size<std::array<T,N> > : std::tuple_size<std::array<T,N> > { };

and here is your fooadjusted / generalized ( live example ):

template < typename T >
void foo( T&& param )
{
    using U = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
    static_assert( 3 == array_size<U>::value, "param must have a size of 3" );
}

T&& param, lvalues.

+8

, , .

template <std::size_t N, typename T, std::size_t Bound>
void check_array_size( T (&)[Bound] )
{
    static_assert(Bound == N, "incorrect array size");
}

template <std::size_t N, typename T, std::size_t Bound>
void check_array_size( const std::array<T,Bound>& )
{
    static_assert(Bound == N, "incorrect array size");
}

template <std::size_t N>
void check_array_size( ... )
{
    static_assert(N<0, "argument is not an array");
}

template <typename T>
void foo(T& param)
{
    check_array_size<3>(param);
    // actual function implementation...
}
+1

, , ( * static_assert *) cArray stdArray , std:: extent :

http://en.cppreference.com/w/cpp/types/extent

, , :

static_assert( std::extent< T >::value == 0, "param is not zero" );

, , std:: extent std:: array, , cArray

AFTER CHANGE OP: Now that you have changed foo to accept the link, you will have this std :: extent reports 3 for cArray and 0 (zero) for stdArray. Therefore, you will have an exception at compile time because the dimension of stdArray is not 3.

0
source

Source: https://habr.com/ru/post/1533604/


All Articles