结构化绑定到const c数组的副本是否应为const? [英] Shall structured binding to a copy of a const c-array be 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 具有数组类型 If the assignment-expression in the initializer has array type 我们有 We have 但是,正如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. 那似乎是对的.当您编写 That seems right. When you write 这篇关于结构化绑定到const c数组的副本是否应为const?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!A
,并且不存在 ref-qualifier ,则e
具有键入 cv A
,并且每个元素都从 assignment-expression 的相应元素进行复制初始化或直接初始化,如 initializer的形式所指定.
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在技术上是正确的. 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.
auto x = y;
时,您肯定会希望x
不是顶级const
,但是在这里,我们仍然会遇到这种情况.我认为目前尚无核心问题,但应该存在. 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.