获取 std::array 的底层 raw (C) 的规范方法是什么
数组?
无法获取底层 C 数组。
另外,data() 返回原始指针是否有充分的理由,而不是
对底层原始数组的引用,或者这只是一个疏忽?
它倒退了:std::array 没有充分的理由提供底层 C 数组。正如您已经说过的,C 数组只有在函数获得对 C 数组的引用时才有用(通过原始指针)。
你上一次使用函数是什么时候:
void foo(int (&arr)[5])
我?绝不。除了获取数组的大小(并拒绝指针)之外,我从未见过带有 C 数组引用参数的函数:
template <class T, std::size_t N>
auto safe_array_size(T (&)[N]) { return N; }
让我们深入了解为什么不使用对数组的参数引用。
对于初学者来说,由于数组到指针的衰减和缺少引用类型,从 C 区域指针和单独的大小参数是传递数组的唯一方法。
在 C++ 中,有 C 数组的替代品,例如 std::vector 和 std::array。但即使你有一个(旧版)C 数组,你也有两种情况:
- 如果将其传递给 C 函数,则没有引用选项,因此您只能使用指针 + 大小
- 当您想将其传递给 C++ 函数时,惯用的 C++ 方法是传递 begin + end 指针。
首先,begin + end 迭代器是通用的,它接受任何类型的容器。但是,当您想避免使用模板时,看到对std::vector 的引用并不少见,那么如果您有一个 C 数组,为什么不引用呢?因为一个很大的缺点:你必须知道数组的大小:
void foo(int (&arr)[5])
这是极其有限的。
要解决这个问题,您需要将其设为模板:
template <std::size N>
void foo(int (&arr)[N])
这超出了避免模板的目的,因此您最好使用 begin + end 模板迭代器。
在某些情况下(例如,仅对 2 或 3 个具有
相同的语义,所以它们不应该是单独的参数)
需要特定的数组大小,并使函数通用
没有意义。在这些情况下,指定数组的大小
保证安全,因为它只允许传入一个数组
在编译时正确的大小;因此它是有利的,不是
“大缺点”
(C 和)C++ 的优点之一是适用范围广。所以是的,你总会发现一些领域以独特的方式使用或需要某种独特的功能。话虽如此,即使在您的示例中,我仍然会回避数组。当您有固定数量的不应该在语义上分离的值时,我认为大多数时候结构将是数组的正确选择(例如glm::mat4 而不是float[4])。
但我们不要忘记std::array 是什么:C 数组的现代替代品。我在分析选项时学到的一件事是没有绝对的“优于”。总有一个“依赖”。但不是在这种情况下:std::array 应该毫无疑问地替换接口中的 C 数组。因此,在需要固定大小的容器作为参考参数的极少数情况下,当您已经拥有std::array 时,鼓励使用 C 数组是没有意义的。因此,需要公开std::array 的底层 C 数组的唯一有效情况是一些具有 C 数组引用参数的旧库。但我认为从大局来看,将其添加到界面中是不合理的。新代码应该使用结构(顺便说一句,std::tuple 越来越容易被每个标准使用)或std::array。