为什么 std::array 中没有运算符>



我正在写一个std::array类作为一个小练习,在此过程中我发现std::array不实现operator->。因此,对于数组,允许以下操作

struct S { int s; };
S c[2];
c->s = 2;

但对于std::array,这是不可能的

struct S { int s; };
std::array<S,2> cpp;
// cpp->s = 2;  // does not compile

使得std::array与c数组不完全兼容。这个决定是有原因的吗?


(我预计会有严厉的反应,但我很惊讶他们来得如此之快)

显然,正如我们所知道的,数组不是指针,只是衰变为指针。c++的问题不在于它们会衰减,而在于它们会自动衰减。如果有人故意为std::array使用->语法,这很可能是糟糕的设计,但不是问题。

即使有operator->,std::array在c++中也会像一等公民一样(这是一个数组)。

c++并不是一种不让用户受到任何伤害的语言。

c->s可以工作,因为像c[2]这样的原始数组,会自动将衰变成表达式中的指针。

所以c->s等于c[0].s

std::array这样的对象不会衰变为指针,也不会提供->T*的重载,因此cpp->s不能工作。


std::array[is]不完全兼容c数组

幸运的是不!它是一个类似数组的对象,解决了许多与原始数组相关的问题。

访问数组的第一个元素,如c->s,可能很好,很简洁,但它的可读性是有问题的,事实上,许多人认为数组衰减是一个问题,而不是一个特性。

CppCoreGuidelines也承认数组到指针的衰减是一个问题领域:

理想情况下,程序应该是完全静态(编译时)类型的安全的。不幸的是,这是不可能的。问题:

工会
  • <
  • 阵列衰变/strong>
  • <
  • 范围错误/gh>
  • 缩小转换

std::array通过禁止它来解决源自C的特性。

c++并不是一门不让用户受到任何伤害的语言

正确的。正如他们所说,"当你的锤子是c++时,一切都变成了大拇指"。但这并不意味着我们不能做任何事情,一次解决一个问题。这就是std::array对原始数组的操作,std::unique_ptr对拥有指针的操作,nullptrNULL的操作,等等。

为什么没有操作符->在std::数组

因为数组不是间接的形式,数组也没有成员,所以提供间接的成员访问操作符没有什么意义。

使用操作符→使用数组是非常容易误导的(在我看来),它只作为数组到指针衰减的副作用。~使用std::array的首要原因有50%是为了避免无意的数组到指针的衰减。

你可能想说

c->s = 2;

代替c->x。当将c声明为数组时,变量c只是指向该数组的第一个元素c[0]的指针,在您的示例中,这是一个结构体。对指针c->s应用操作符->c[0].s相同。当使用std::array时,变量cpp不表示指向第一个元素的指针。因此,箭头操作符在这里没有任何意义。

最新更新