常数组

fre*_*low 20 c++ arrays templates const

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

int a[10];
Run Code Online (Sandbox Code Playgroud)

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

const int b[10];
Run Code Online (Sandbox Code Playgroud)

在C++中,似乎有两种方法来定义std::arrays const:

std::array<const int, 10> c;
const std::array<int, 10> d;
Run Code Online (Sandbox Code Playgroud)

这两个定义是否相同?如果是这样,那个惯用的是什么?如果没有,有什么区别?

ten*_*our 12

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

1:

std::array<const int, 10> c;
Run Code Online (Sandbox Code Playgroud)

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

这段代码意味着它c是可变的,但元素本身不是.然而,在实践中,没有突变就c不会影响元素.

2:

const std::array<int, 10> d;
Run Code Online (Sandbox Code Playgroud)

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

在实践中,它们在可变性方面的行为都相似,因为可变操作array始终触及元素.


Ste*_*sop 6

他们是不等价的- c.referenceint&d.referenceconst int&(不是说你可以使用该语法访问类型定义,但你可以捕捉模板参数推导类型和分辨).

但我很确定tenfour有一个关键的观察结果,"没有突变就c不会影响元素".因此,就实际对阵列所做的任何事情而言,它们都是相同的,因为它们的类型不同,它们只有不同的元数据.

我能想到的主要情况是,如果在接口中使用类型本身(而不是采用迭代器或范围模板参数).我会说当把它作为指针或参考参数时,你应该array类型本身进行const限定,因为它不需要任何费用,并允许调用者使用你的函数,无论他们做出哪种选择.您可以 const的,限定元素类型,但所使用的任何一种是与另一个不兼容,所以基本上每个人都同意其使用,否则会有需要进行一些复制.我认为这需要积极协调风格,因为我怀疑你会让全世界的每个人都同意哪种方式最好.const int可能有更好的情况,原则上你应该const尽一切可能,但我希望int人们将使用谁根本没有想过它,因为他们已经习惯了所有那些可以'C++ 03容器' t有一个const值类型.


Pav*_*ban 5

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

const std::array<const int,10> c;
Run Code Online (Sandbox Code Playgroud)

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

  • 声明时,两个数组都需要初始化 恕我直言,两者之间没有区别 - 它们在算法和使用方面完全相同(实际上,迭代器是相同的;`const int*`).坦率地说,最好的声明方式就像在答案中所说的那样,`const std :: array <const int,10> c;`这使得它非常具体,是const int的const数组. (3认同)