为什么包含< utility>打破GCC中的结构化绑定? [英] Why does including <utility> break structured bindings in 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?
推荐答案
这是编译器错误 GB 20 , LWG 2446 ),这会导致gcc/libstdc ++在此处表现出这种行为. 意向可以肯定,无论是否使用#include <utility>
,代码都可以正常工作,这只是标准措辞正确到位的问题.
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 ofE
or of the same unambiguous public base class ofE
,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 ofE
. Designating the non-static data members ofE
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.
这篇关于为什么包含< utility>打破GCC中的结构化绑定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!