临时数组的元素本身不是重值吗?
Aren't elements of a temporary array rvalues themselves?
using intArray = int[];
int (&a) [4] = intArray{1, 2, 3, 4};
这是不允许的,因为将非const左值引用绑定到临时(右值)是非法的。g++ 4.9.1和clang 3.4.2都带着错误返回;当a
是符合const
条件的
int const (&a) [4] = intArray{1, 2, 3, 4};
然而,当我这样做时
int &x = intArray{1, 2, 3, 4} [1];
两个编译器都可以很好地编译它,没有错误。挖掘标准(草案N3337)对此,§5.2.1 Subscripting
说
1后缀表达式后跟方括号中的表达式是后缀表达式。其中一个表达式的类型应为"指向T的指针",另一个表达式的类型应为无作用域枚举或整型。结果是类型为"T"的左值。类型"T"应该是完全定义的对象类型。表达式E1[E2]与(根据定义)*((E1)+(E2))
相同。2 带括号的init-list不能与内置下标操作符一起使用。
如果我使用1,那么我不明白为什么标准允许构建临时数组,因为在其中下标一个元素会给出一个左值,即我可以从临时数组中获得一个左值,这与临时数组只能绑定到const左值引用或右值引用的原始概念相矛盾。
如果我去2那么为什么编译器不抛出错误,当我做
{1, 2, 3, 4}[1]
?
问题1
关于不将临时值绑定到左值的规则并不能提供绝对的安全性。它可以防止这类错误的一部分,但不是全部。我怀疑,为了防止所有这些错误,需要将"临时"的概念纳入类型系统,就像const
一样。然后,如果您知道不会将引用保存的时间超过临时引用的生命周期,则可以"抛弃临时引用"。委员会认为我们现有的规则是值得的,想必他们也认为继续努力是不值得的。
另一个例子,vector<int>(4)[0]
也返回一个左值,即使operator[]
调用是在临时对象上进行的。标准不会因为这个而禁止临时向量的构造,我也不认为它应该禁止临时数组。好的,所以vector
是一个用户定义的类型,而数组是内置的,但除此之外,我认为情况是相似的。
如果您使用数组,特别是临时数组,那么在某种程度上,标准认为您得到了您应得的。它不会仅仅因为可以从临时数组中获得左值就禁止使用临时数组。
但是,我认为你有一个有效的总体观点。下标可能可以在数组右值上更安全地定义,因为编译器有必要的信息。它可以求值为右值,其值为对应数组元素的值。这可能会令人困惑或不方便,因为它与通常的下标表达式不一致,但它会更安全:-)如果你写struct A {int a;}
,那么A().a
是一个右值,所以我不认为将该原则应用于数组是完全不可能的。当然,这将是一个突破性的变化。
问题2
没有在大括号初始化列表上使用下标。您是在使用new-style初始化器语法构造的临时对象上使用它。也就是说,表达式解析的是(intArray{1, 2, 3, 4})[1]
,而不是intArray({1, 2, 3, 4}[1])
。
- 数组元素打印的递归方法
- 如何将字节数组元素替换为修改的十六进制 ASCII 符号?
- 为什么使用数组元素查找最大数字的程序不起作用?
- 数组元素更改值?
- 如何访问宏中定义的数组元素
- 将数组元素递增 1
- C++函数,它将数组、谓词和运算符作为参数,并将运算符应用于满足谓词的数组元素
- 存储指向动态数组元素的指针
- C++通过别名指针以静默方式将错误的类型分配给数组元素
- 在 std::map 中插入数组元素
- 使用指针访问数组元素时出现意外结果
- c++ 使用动态分配运算符反向数组元素
- 为什么在 c++ 中分配 char 数组元素时,分配的字符会被销毁?
- 缺少数组元素问题
- 如何在类中制作 2D 数组元素,然后在其构造函数中指定其维度?
- 创建一个函数来转换数组元素的类型并返回数组的地址
- 删除在结构 c++ 中声明的数组元素
- Getter 和 Setter 用于类 C++ 中的数组元素
- 尝试递归获取数组元素的总和
- 使用SWIG将numpy数组元素(int)传递给c++int