为什么包含< utility>打破GCC中的结构化绑定? [英] Why does including <utility> break structured bindings in GCC?

查看:127
本文介绍了为什么包含< utility>打破GCC中的结构化绑定?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑:

struct Point { int x, y; };

int main()
{
    const auto [x, y] = Point{};
}

此代码可以在C ++ 17模式下使用gcc 7.1很好地进行编译,但是可以使用以下代码:

This code compiles fine with gcc 7.1 in C++17 mode, however this one:

#include <utility>

struct Point { int x, y; };

int main()
{
    const auto [x, y] = Point{};
}

出现错误:

bug.cpp: In function 'int main()':
bug.cpp:7:16: error: 'std::tuple_size<const Point>::value' is not an integral constant expression
     const auto [x, y] = Point{};
                ^~~~~~

这是怎么回事?编译器错误,或者这是结构化绑定应该如何工作的?

What's going on here? A compiler bug, or is this how structured bindings are supposed to work?

推荐答案

这是编译器错误

This is compiler bug 78939. Although it's a bit more complicated than that - there were a few issues between the core language and the library that were mutually contradictory (GB 20, LWG 2770, and LWG 2446), which lead to the kind of behavior that gcc/libstdc++ exhibit here. It is certainly intended that the code work with or without #include <utility>, it's just a matter of the standard wording having gotten there properly.

是的,根据 [dcl.struct.bind]/4 :

否则,E的所有非静态数据成员均应为E的公共直接成员,或为E的相同明确的公共基类,E不得具有匿名联合成员,标识符列表中的元素数量应等于E的非静态数据成员的数量.将E的非静态数据成员指定为m0,m1,m2 ...(按声明顺序),每个vi是一个左值的名称,该左值引用e的成员mi,其类型为cv Ti,其中Ti是该成员的声明类型;引用的类型为cv Ti.如果该成员是位字段,则左值是位字段. [示例:

Otherwise, all of E's non-static data members shall be public direct members of E or of the same unambiguous public base class of E, E shall not have an anonymous union member, and the number of elements in the identifier-list shall be equal to the number of non-static data members of E. Designating the non-static data members of E as m0, m1, m2, ... (in declaration order), each vi is the name of an lvalue that refers to the member mi of e and whose type is cv Ti, where Ti is the declared type of that member; the referenced type is cv Ti. The lvalue is a bit-field if that member is a bit-field. [ Example:

struct S { int x1 : 2; volatile double y1; };
S f();
const auto [ x, y ] = f();

这与包含<utility>完全无关,此代码中的任何内容都不依赖于任何库功能-成员是直接获取的,而不是通过get/tuple_size机制获取的.

This is completely unrelated to the inclusion of <utility>, nothing in this code depends on any library functionality - the members are grabbed directly, and not via the get/tuple_size mechanism.

这篇关于为什么包含&lt; utility&gt;打破GCC中的结构化绑定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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