Search code examples
c++arraysdynamic-arrays

Cast between const char* [][3] and std::array< const char*, 3 >*


I need a way to cast between these two types of variables:

std::array< const char*, 3 >* foo;
const char* foo[][3];

Because I need to be able to pass both types to a function. The function can be defined either of these ways, whichever makes conversion easier:

void bar( std::array< const char*, 3 >* param );
void bar( const char* param[][3] );

In this question, Jarod42 suggests using the method here. Is there a cleaner way to do this?

Edit in response to dyp's link

This reinterpret_cast did work for me, but Ivan Shcherbakov describes it as an "ugly dirty hack" I've pasted the code, below... I don't understand why this is a hack, or why something could go wrong with it? Is the template method suggested by Nathan Monteleone necessarily better than this?

void bar( std::array< const char*, 3 >* param ){}

void main( void )
{
    static const char* cStyle[][3] = { NULL };
    std::array< const char*, 3 > foo = { NULL };
    std::array< const char*, 3 >* stlStyle = &foo;

    bar( reinterpret_cast< std::array< const char*, 3 >* >( cStyle ) );
    bar( stlStyle );
}

Solution

  • Based on Nathan Monteleone's solution:

    template<typename T>
    enable_if_t<conditional_t<is_array_v<T>, extent<T>, tuple_size<T>>::value == 3U> bar(T* param){}
    

    I believe this solution is the best of all worlds, cause it avoids the reinterpret_cast that is implementation dependent. And it enforces that param must be of size 3 at compile time.

    Note that the conditional_t's value is called only after a type is selected. For more on this see: Short Circuiting Operators in an enable_if

    Live Example