常量数组

发布于 2024-12-10 10:47:50 字数 319 浏览 0 评论 0原文

这是一个很好的旧 C 数组:

int a[10];

这是一个很好的旧 C 数组,它是 const:

const int b[10];

在 C++ 中,似乎有两种方法来定义 std::array它们是 const:

std::array<const int, 10> c;
const std::array<int, 10> d;

这两个定义等效吗?如果是这样,惯用的是什么?如果不是,有什么区别?

This is a good old C array:

int a[10];

And this is a good old C array that is const:

const int b[10];

In C++, there seem to be two ways to define std::arrays that are const:

std::array<const int, 10> c;
const std::array<int, 10> d;

Are these two definitions equivalent? If so, what is the idiomatic one? If not, what are the differences?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

酸甜透明夹心 2024-12-17 10:47:50

好吧,原来的 const int b[10]; 仅当您可以初始化数组时才有用,因此这两个 std::array 示例在实践中都不起作用。

1:

std::array<const int, 10> c;

这最接近于const int c[10];。问题是它没有默认的构造函数,并且因为元素不可变,所以使用它是没有价值的。您必须在构造函数中为其提供一些初始化。按原样,它将给出编译器错误,因为默认构造函数未初始化元素。

此代码意味着 c 是可变的,但元素本身不是可变的。但实际上,c 上不存在不影响元素的突变。

2:

const std::array<int, 10> d;

这意味着 d 不可变,但元素是可变类型 int。因为 const 将传播到成员,这意味着调用者仍然不能改变元素。与上面的示例类似,您需要初始化 d,因为它是 const

实际上,它们在可变性方面的行为相似,因为数组上的可变操作总是触及元素。

Well, the original const int b[10]; is only useful when you can initialize the array, so both of the std::array examples don't work in practice.

1:

std::array<const int, 10> c;

This is the closest to const int c[10];. The problem is there will be no default constructor for it, and because the elements are not mutable, it's worthless to use this. You must provide some initialization for it in the constructor. As-is, it will give a compiler error because the default constructor did not initialize the elements.

This code means that c is mutable, but the elements themselves are not. In practice, however, there are no mutations on c that don't affect the elements.

2:

const std::array<int, 10> d;

This means d is not mutable, but the elements are of mutable type int. Because const will propagate to the members, it means the elements are still not mutable by the caller. Similar to the above example, you will need to initialize d because it's const.

In practice, they will both behave similarly with respect to mutability, because mutable operations on array always touch the elements.

离不开的别离 2024-12-17 10:47:50

它们并不等价 - c.referenceint&d.referenceconst int& (并不是说您可以使用该语法来访问 typedef,而是您可以通过模板参数推导来捕获类型并分辨出区别)。

但我很确定 tenfour 有关键的观察结果,“c 上没有不影响元素的突变”。因此,就您实际对数组执行的任何操作而言,它们是相同的,只是由于它们的类型不同而具有不同的元数据。

我能想到的主要情况是,如果您在接口中使用类型本身(而不是采用迭代器或范围模板参数),那么它会产生影响。我想说,当将其作为指针或引用参数时,您应该对数组类型本身进行 const 限定,因为它不需要您花费任何成本,并且允许调用者使用您的无论他们做出什么选择,函数都会发挥作用。您可以对元素类型进行const限定,但是无论您使用哪一种都与另一种不兼容,因此基本上每个人都必须同意使用哪一种,否则将需要进行一些复制。我认为,这需要在风格上进行积极的协调,因为我怀疑你能否让世界上的每个人都同意哪一个是最好的。 const int 可能有更好的情况,原则上你应该const你能做的一切,但我预计 int 是人们会使用的根本没有考虑过这个问题,因为他们已经习惯了所有那些不能有 const 值类型的 C++03 容器。

They aren't equivalent -- c.reference is int& whereas d.reference is const int& (not that you can use that syntax to access typedefs, but you could capture the type by template argument deduction and tell the difference).

But I'm pretty sure tenfour has the key observation, "there are no mutations on c that don't affect the elements". So as far as anything you actually do to the arrays is concerned they're the same, they just have different meta-data because of their different types.

The main case I can think of where it would make a difference is if you use the type itself in an interface (as opposed to taking an iterator or range template parameter). I'd say that when taking it as a pointer or reference parameter you should const-qualify the array type itself, since it costs you nothing and allows the caller to use your function whichever choice they made. You may const-qualify the element type, but whichever one you use is incompatible with the other one, so basically everyone has to agree which to use or else there will be some copying required. That requires active co-ordination as to style, I think, since I doubt that you'll get everyone in the world to agree which is best. const int probably has the better case, on the principle that you should const everything you can, but I expect int is what people will use who haven't thought about it at all, since they're used to all those C++03 containers that can't have a const value type.

长发绾君心 2024-12-17 10:47:50

上面的定义在堆栈上分配一个常量整数数组,而第二个定义则分配一个可变整数常量数组。在第一种情况下,您必须在声明数组时定义数组的内容,因为它的内容是常量,以后无法修改。我想,第一个第二个声明也会生成类似的东西,

const std::array<const int,10> c;

因为静态数组总是在堆栈上分配,并且指向其第一个元素的指针以后不能被修改。

The upper definition allocates an array of constant integers on the stack, whereas the second one allocates a constant array of variable integers. In the first case, you must define the contents of the array when you declare it, since its content is constant and it cannot be modified later. I guess, the first second declaration will also generate something like

const std::array<const int,10> c;

since a static array is always allocated on the stack and the pointer to its first element cannot later be modified.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文