Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 不是';临时数组的t元素自身是否为右值?_C++_Arrays_C++11_Temporary_Rvalue - Fatal编程技术网

C++ 不是';临时数组的t元素自身是否为右值?

C++ 不是';临时数组的t元素自身是否为右值?,c++,arrays,c++11,temporary,rvalue,C++,Arrays,C++11,Temporary,Rvalue,这是不允许的,因为将非常量左值引用绑定到临时(右值)是非法的。g++4.9.1和Clang3.4.2都有错误;当a符合const条件时,它可以正常编译 using intArray = int[]; int (&a) [4] = intArray{1, 2, 3, 4}; 然而,当我这样做的时候 int const (&a) [4] = intArray{1, 2, 3, 4}; 两个编译器都编译得很好,没有错误。为此挖掘标准(草案N3337),§5.2.1订阅 1后缀表达式

这是不允许的,因为将非常量左值引用绑定到临时(右值)是非法的。g++4.9.1和Clang3.4.2都有错误;当
a
符合
const
条件时,它可以正常编译

using intArray = int[];
int (&a) [4] = intArray{1, 2, 3, 4};
然而,当我这样做的时候

int const (&a) [4] = intArray{1, 2, 3, 4};
两个编译器都编译得很好,没有错误。为此挖掘标准(草案N3337),
§5.2.1订阅

1后缀表达式后跟方括号中的表达式是后缀表达式。其中一个表达式应具有“指向T的指针”类型,另一个表达式应具有非范围枚举或整数类型结果是“T”类型的左值。类型“T”应为完全定义的对象类型。表达式E1[E2]根据定义与*((E1)+(E2))相同

2带括号的初始列表不得与内置下标运算符一起使用。

  • 如果我使用1,那么我不明白为什么标准允许构造临时数组,因为在其中订阅一个元素会给出一个左值,也就是说,我可以从一个临时数组中得到一个左值,它与临时数组的原始概念相矛盾,只能绑定到常量左值引用或右值引用

  • 如果我使用2,那么为什么编译器在我执行
    {1,2,3,4}[1]
    时不抛出错误

  • 问题1

    关于不将临时变量绑定到左值的规则并不能提供铁一般的安全性。它可以防止这类错误的一部分,但不是全部。我怀疑,为了防止所有此类错误,需要将“暂时性”的概念纳入类型系统,就像
    const
    一样。然后你可以“抛弃暂时性”,如果你知道你不会将引用保留超过暂时性的生命周期。委员会认为我们的规则是值得的,大概他们也认为继续努力是不值得的

    另一个例子是,
    vector(4)[0]
    也返回一个左值,即使
    操作符[]
    调用是在一个临时变量上进行的。标准不会因此而禁止构建临时向量,我也不认为它应该禁止临时数组。好的,
    vector
    是一种用户定义的类型,而数组是内置的,但除此之外,我认为情况类似

    如果您使用数组,尤其是临时数组,那么在某种程度上,标准认为您得到了应得的。它不会仅仅因为可以从一个数组中得到左值就禁止临时数组

    不过,我认为你有一个正确的一般观点。在数组右值上定义下标可能更安全,因为编译器具有必要的信息。它可以计算为一个右值,其值是对应数组元素的值。这可能会让人困惑或不方便,因为它与通常的下标表达式不一致,但会更安全:-)如果您编写
    struct A{int A;}
    ,那么
    A()。A
    是一个右值,所以我认为将该原则应用于数组并不是完全不可能的。当然,这将是一个突破性的改变

    问题2


    您没有在带括号的init列表上使用下标。您正在一个临时文件上使用它,该文件恰好是使用新型初始值设定项语法构造的。也就是说,您的表达式解析
    (intArray{1,2,3,4})[1]
    ,而不是
    intArray({1,2,3,4}[1])

    ,但是对该元素的引用不会挂起,因为整个数组是临时的,可能很快就会消失?@legends2k:是的,它会。您的问题似乎包含这样一种假设,即标准旨在防止这种情况在格式良好的代码中发生,但标准没有。它只有一条规则,可以捕获一大类错误,并得到相应的结果。或者我认为有两条规则:(1)不能将临时引用绑定到非常量引用;(2)使用临时初始值设定项声明常量引用可以延长临时引用的寿命。您的问题似乎包含一个假设,即该标准旨在防止这种情况在格式良好的代码中发生,但该标准没有。是的,我想这是一个远眺。如果可能的话,你能给我指一下《标准》中显示这种宽大处理的其他例子吗?
    int &x = intArray{1, 2, 3, 4} [1];