[英]Why does std::array not have an operator T*?
对于C数组,通常情况下,简单地命名数组与写&foo[0]
差不多有50年的历史。
在我正在处理的项目中,从C样式数组转换为std :: array <>时,出现的绝大多数“错误”是由于C数组的上述特性引起的。
在所有情况下,解决方案都是微不足道的,只需追加.data()
。 但是我想到精心设计的operator T*
应该直接解决这个问题。
有任何技术原因无法创建此运算符?
C样式数组是按大小构造的。 您可以通过各种方式获得数组的编译时大小。 但是,当数组衰减为指针时,您将失去编译时大小调整信息。 即使参数是“数组”类型,它实际上仍然只是没有大小信息的指针。 如果数组作为函数参数传递( template<size_t S> void func(T(¶m)[S])
),则可以使用模板编程来保留大小。
许多C ++程序员认为数组到指针的隐式衰减是C样式数组中的设计缺陷 。 确实,有损转换很可能不是应该隐含的转换,这并非不合理。 鉴于std::array
试图修复尽可能多的C样式数组的缺陷,使其隐式衰减为指针将适得其反。
相比之下, C ++ 20的std::span
类型提供了从std::array
(以及C型数组等)的隐式转换。 原因是这样的转换保留了信息:指针以及大小。 实际上,转换甚至可以保留该大小的编译时性质。
有任何技术原因无法创建此运算符?
“ 无法 ”? 没有。
引入data()使其在多个STL容器中具有相似的接口。 例如,std :: string和std :: vector也提供data(),它提供了实际数据缓冲区的地址。 因此,std :: array接口旨在匹配该接口。 您建议的Operator()是完全不同的方式,并且似乎并非绝对合适。 正如上面的评论者还提到的那样,更合适的是运算符T *(),但这仍然不是STL设计人员喜欢的方式-他们引入了data()。 为什么? 也许是因为它更具可读性。
有什么充分的理由不存在该运算符?
如果您要说为什么没有operator T*()
自动提供转换,则(多个)潜在原因之一就是自动转换的想法。
使用std::array
的代码通过利用operator T*()
正确地编译可能会很方便,而您却可以使用没有错误构建的程序。 但是,这有一些含义:
1)对operator T*()
)的调用是程序员可能不希望看到的潜在运行时成本,而只是随之而来。 在C ++中,目标是仅支付所需的费用,而强制转换运算符只是强加自己就违背了这一想法。
2)由于程序员不了解的用法, operator T*()
和强制转换操作符通常可能会隐藏正在运行的代码中的错误或瓶颈。
以我的经验,请问一个代码基础上满是强制转换运算符的程序员,实际上实际上正在调用什么函数,而且不止一次,他们不确定他们的代码采用了什么路径,或者只是犯错了(而且不要直到他们参加调试会话并看到被看似无辜的转换操作员正在做的所有曲折之前,才意识到这一点。
因此,对于程序员来说,显式地希望通过调用诸如data()
类的函数而不是利用他们可能没有意识到的operator T*()
来“转换”数据,要安全得多。
调用data()
是您应避免的事情。 拥有这种功能可能会很有用(例如,在我们的示例中,迁移代码或优化代码处理内脏),但是它有悖于安全网std::array
提供的安全性。
std::array<int, 2> a{1,2};
auto* ptr = a.data();
std::cout << ptr[2]; // boom
剥夺安全网的事物应该是明确的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.