到 const c 数组副本的结构化绑定应该是 const 吗?

2024-04-21

考虑这段代码(demo https://godbolt.org/z/Nmz-gN):

#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?)
    }

A 结构化绑定到一个副本const声明了 c 数组const由 Clang 和非常量 by GCC.

GCC 对 c 数组的行为与对聚合或类元组类型观察到的行为一致。

另一方面,从我对标准的阅读来看,我认为 Clang 遵循了所写的内容。在[dcl.struct.bind]/1 http://eel.is/c++draft/dcl.struct.bind#1.sentence-4 e 具有 cv A 型其中 A 是初始化表达式的类型,cv是结构化绑定声明的 cv 限定符。以及初始化表达式的类型ar相应地[表达式类型]/1 http://eel.is/c++draft/expr.type#1.sentence-1 const int[2].

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


该标准的措辞在[dcl.struct.bind] http://eel.is/c++draft/dcl.struct.bind says:

If the 赋值表达式 in the 初始化器具有数组类型A and no 引用限定符存在,e有类型cv A每个元素都是从相应的元素复制初始化或直接初始化的赋值表达式按照表格的规定初始化器.

We have auto [i,j] = ar;, ar具有数组类型const int[2],标准的措辞明确表明e有类型const int[2]. Thus, 根据措辞,每个绑定都引用元素类型 - 即const int。 Clang 在技术上是正确的。

然而,正如理查德·史密斯在《海湾合作委员会错误 80649 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86049:

我认为这是标准中的一个错误。数组类型的 cv 限定符应该被丢弃,因为它们对于任何正常的自动推导都是如此。

看来是对的。当你写的时候auto x = y;你肯定会期望x不成为顶级const,但这里的情况仍然如此。我认为目前还没有解决这个问题的核心问题,但应该有。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

到 const c 数组副本的结构化绑定应该是 const 吗? 的相关文章

随机推荐