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

6
我需要一种将这两种类型的变量进行转换的方法:
std::array< const char*, 3 >* foo;
const char* foo[][3];

因为我需要能够将这两种类型传递给一个函数。该函数可以通过以下任一方式定义,以使转换更加容易:

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

这个问题中,Jarod42建议使用这里的方法。有没有更简洁的方法来做到这一点? 根据dyp链接进行编辑 这个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 );
}

我们可以知道你想要在foo中存储什么内容吗? - edmz
dyp,我认为关键在于没有指定对齐方式,是的,foo的两个版本应该完全兼容。black,这个变量将包含3个动态分配的C字符串数组。 - Jonathan Mee
@Jeffrey 这只是一个简化版。那些维度将会被动态分配。 - Jonathan Mee
@JonathanMee,那你为什么不使用std :: vector呢? - Shoe
显示剩余14条评论
2个回答

3

就我个人而言,你可以做的最简单、最优雅的方法是将你的栏功能作为一个模板。

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,则更难存储指向数组的指针。

我认为我可以使用extents来进行static_assert,以确保大小为3,对吗?然后我就可以继续进行统一实例化了。 - Jonathan Mee
@JonathanMee 你可能可以。我以前从未使用过std::extent,所以想知道你是否成功了。 - Nathan Monteleone
Nathan Monteleone,我没有像我希望的那样成功。我在使用std::extent时遇到了问题,无论是在std::array还是C风格数组上都是如此。不过,我想让它起作用,因为根据Ivan Shcherbakov的说法,如果我不这样做,我就是一个坏人。为此,我创建了一个新问题:https://dev59.com/Q37aa4cB1Zd3GeqPmB9x - Jonathan Mee

2
基于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的值。更多信息请参见: enable_if中的短路运算符 在线示例

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接