结构化绑定到const c数组的副本是否应为const? [英] Shall structured binding to a copy of a const c-array be const?

查看:97
本文介绍了结构化绑定到const c数组的副本是否应为const?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下代码(演示):

#include <tuple>
#include <type_traits>

struct Ag{int i;int j;};
using  T = std::tuple<int,int>;
using  Ar = int[2];

const Ag ag {};
const T t   {};
const Ar ar {};

void bind_ag(){
    auto [i,j] = ag;
    static_assert(std::is_same_v<decltype((i)),int&>);
    }
void bind_t(){
    auto [i,j] = t;
    static_assert(std::is_same_v<decltype((i)),int&>);
    }
void bind_ar(){
    auto [i,j] = ar;
    static_assert(std::is_same_v<decltype((i)),int&>);       //For GCC
    static_assert(std::is_same_v<decltype((i)),const int&>); //For Clang (and standard?)
    }

const c数组副本的结构化绑定由Clang声明为 const ,而GCC声明为 non-const .

A structured binding to a copy of a const c-array are declared const by Clang and non-const by GCC.

c阵列的GCC行为与聚集或类似元组的类型所观察到的行为一致.

The behavior of GCC for c-array is consistent with the behavior observed for aggregate or tuple-like types.

从另一方面看,我认为Clang遵循所写的内容.在 [dcl.struct.bind]/1 e的类型为cv A ,其中A是初始化表达式的类型,而 cv 是结构化绑定声明的cv限定词.并且初始化程序表达式ar的类型相应于 [expr.类型]/1 const int[2].

On the other hand from my reading of the standard, I suppose Clang follows what is written. In [dcl.struct.bind]/1 e has type cv A where A is the type of the initializer expression and the cv is the cv-qualifier of the structured binding declaration. And the type of the initializer expression ar is accordingly to [expr.type]/1 const int[2].

应该期待什么?我的观点是Clang遵循标准.另一方面,我的意图是数组,聚合和类似元组的类型的行为是等效的.

What should be expected? My opinion is that Clang follows the standard. On the other hand I feel the intent was that the behaviors for array, aggregate and tuple-like types were equivalent.

推荐答案

如果初始化器中的 assignment-expression 具有数组类型A,并且不存在 ref-qualifier ,则e具有键入 cv A,并且每个元素都从 assignment-expression 的相应元素进行复制初始化或直接初始化,如 initializer的形式所指定.

If the assignment-expression in the initializer has array type A and no ref-qualifier is present, e has type cv A and each element is copy-initialized or direct-initialized from the corresponding element of the assignment-expression as specified by the form of the initializer.

我们有auto [i,j] = ar;ar的数组类型为const int[2],标准的措辞清楚地表明e的类型为const int[2].因此,按照措辞,每个绑定都引用元素类型-const int. lang在技术上是正确的.

We have auto [i,j] = ar;, ar has array type const int[2], and the wording of the standard makes it clear that e has type const int[2]. Thus, per the wording, each binding references the element type - which is const int. Clang is technically correct.

但是,正如Richard Smith在 gcc错误80649 中指出的那样:

However, as Richard Smith points out in gcc bug 80649:

我认为这是标准中的错误.数组类型的cv限定词应该被丢弃,就像任何正常的自动推论一样.

I think this is a bug in the standard. The cv-qualifiers of the array type should be discarded, as they would be for any normal auto deduction.

那似乎是对的.当您编写auto x = y;时,您肯定会希望x不是顶级const,但是在这里,我们仍然会遇到这种情况.我认为目前尚无核心问题,但应该存在.

That seems right. When you write auto x = y; you'd certainly expect x to not be top-level const, but here we have a situation where it still is. I don't think there's a Core issue open for this yet, but there should be.

这篇关于结构化绑定到const c数组的副本是否应为const?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆