9

据我所知,可以编写以下代码:

char *a = new char[50];
for (int i = 0; i < 50; ++i) {
    i[a] = '5';
}

它编译。有用。它的作用

char *a = new char[50];
for (int i = 0; i < 50; ++i) {
    a[i] = '5';
}

难道仅仅是因为:

  • a[b]默认情况下被实现为宏*(a + b),两个代码示例都有效的事实只是意外/编译器特定的
  • 它在某处标准化,并且此类算法的结果在每个平台上都应该相同

假设加法应该是可交换的是合理的,但如果我们operator[]以这种方式实现,我们已经使其他东西可交换,这可能不是我们想要的。

有趣的事实是没有pointer[pointer]运算符,所以operator[]也不是宏。

我知道这很糟糕。我知道这会让阅读代码的人感到困惑。但我想知道这是否只是一个意外,它在独角兽有七只腿且左脸颊上有角的遥远土地上行不通。

4

3 回答 3

13

C++ 标准,第 8.3.4 节,注释 7(第 185 页)(强调我的)。

除了已为类 (13.5.5) 声明的情况外,下标运算符[]的解释方式E1[E2]*((E1)+(E2)). 由于适用于 的转换规则+,如果E1是数组和E2整数,则E1[E2]指的是 的E2-th 成员E1。因此,尽管它的外观不对称,但下标是一种交换操作

于 2014-05-26T14:55:53.390 回答
4

以下是 C++11 标准的内容:

注意:除了已为类 (13.5.5) 声明外,下标运算符[]的解释方式E1[E2]*((E1)+(E2)). 由于适用于 + 的转换规则,如果E1是数组和E2整数,则E1[E2]指的是 的E2第 - 个成员E1。因此,尽管它的外观不对称,但下标是一种交换操作。(重点已添加)。

a[b]因此,您实现的假设*(a + b)是正确的,只是它直接在编译器中实现,而不是作为宏实现。

于 2014-05-26T14:56:10.347 回答
1

表达式 E1[E2] 与 *((E1)+(E2)) 相同(根据定义)

...然后索引和指针的交换性占据主导地位。请参阅此版本中的友好社区 C++ 标准第 5.2.1 节:http ://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3485.pdf

于 2014-05-26T14:55:12.583 回答