在const char * [] [3]和std :: array<之间转换const char *,3> *

时间:2014-03-26 19:51:27

标签: c++ arrays dynamic-arrays

我需要一种在这两种变量之间进行转换的方法:

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

因为我需要能够将两种类型都传递给函数。该功能可以通过以下方式定义,无论哪种方式使转换更容易:

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

this问题中,Jarod42建议使用方法here。有更清洁的方法吗?

编辑以回复dyplink

reinterpret_cast对我有用,但是Ivan Shcherbakov将其描述为“丑陋的黑客”我粘贴了代码,下面......我不明白为什么这是一个黑客,或者为什么会出现问题呢? Nathan Monteleone建议的模板方法是否必然比这更好?

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

2 个答案:

答案 0 :(得分:2)

在我的头顶,你能做的最简单最优雅的事情就是让你的酒吧功能成为一个模板。

template <class T> void Tbar( T param ) {
    char c12 = param[1][2];    // (for example)
}

当然,在那一点上你失去了执行它的大小[3]的能力。所以你可以做一些事情,比如在源文件中隐藏模板实现,将两个原始函数作为原型暴露在头文件中,然后在cpp文件中实现为

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

这种方法的优点是它完全避免了铸造。我认为,缺点是你在Tbar中可以做的事情有点受限,即你只限于char*[][3]array<char*, 3>*共有的任何操作。例如,如果Tbar是非模板类中的setter,那么存储指向数组的指针也会更加困难。

答案 1 :(得分:1)

基于Nathan Monteleone的解决方案:

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

我相信这个解决方案是所有世界中最好的,因为它避免了依赖于实现的reinterpret_cast。并且它强制param在编译时的大小必须为3。

请注意,仅在选择类型后才会调用conditional_t的值。有关详情,请参阅:Short Circuiting Operators in an enable_if

Live Example