简体   繁体   English

当前的标准草案似乎无法解释为什么两个结构化绑定声明相互冲突

[英]It seems the current standard draft cannot interpret why two structured binding declaration conflict with each other

struct A{
    int a;
};
struct B{
    int b;
};
auto&& [x] = A{};  //#1
auto&& [x] = B{};  //#2
int main(){
}

In this example, all compilers give an error that the x at #2 conflicts with that introduced at #1.在这个例子中,所有编译器都会给出一个错误,即 #2 处的x与 #1 处引入的 x 冲突。 However, IIUC, there's no rule in the post-C++20 working draft standard which can interpret what's the reason.但是,IIUC,后 C++20 工作草案标准中没有任何规则可以解释原因。

First, in my opinion, the declaration at #2 and the declaration at #1 declare the same entity.首先,在我看来,#2 的声明和#1 的声明声明了同一个实体。 They correspond due to: basic.scope#scope-3它们对应于: basic.scope#scope-3

Two declarations correspond if they (re)introduce the same name , both declare constructors, or both declare destructors, unless如果两个声明(重新)引入相同的名称、都声明构造函数或都声明析构函数,则两个声明对应,除非

[...] [...]

They declare the same entity per basic.link#8他们根据basic.link#8声明相同的实体

Two declarations of entities declare the same entity if, considering declarations of unnamed types to introduce their names for linkage purposes, if any ([dcl.typedef], [dcl.enum]), they correspond ([basic.scope.scope]), have the same target scope that is not a function or template parameter scope , and either两个实体声明声明同一个实体,如果考虑到未命名类型的声明以引入它们的名称以用于链接目的,如果有的话([dcl.typedef],[dcl.enum]),它们对应([basic.scope.scope]) ,具有相同的目标 scope 不是 function 或模板参数 scope ,或者

  • they appear in the same translation unit , or它们出现在同一个翻译单元中,或者
  • [...] [...]

So, as far as now, they declare the same entity and they shouldn't be considered as potentially conflict per basic.scope#scope-4因此,就目前而言,它们声明了相同的实体,并且不应将它们视为每个basic.scope#scope-4的潜在冲突

Two declarations potentially conflict if they correspond and cause their shared name to denote different entities([basic.link]) .如果两个声明对应并导致它们的共享名称表示不同的实体([basic.link]) ,则它们可能会发生冲突。 The program is ill-formed if, in any scope, a name is bound to two declarations that potentially conflict and one precedes the other ([basic.lookup]).如果在任何 scope 中,一个名称绑定到两个可能冲突的声明并且一个在另一个之前([basic.lookup]),则该程序是格式错误的。

Since they denote the same entity, as aforementioned, they do not potentially conflict.如前所述,由于它们表示相同的实体,因此它们没有潜在的冲突。

They still do not violate this rule:他们仍然没有违反这条规则:
basic.link#11 basic.link#11

For any two declarations of an entity E:对于实体 E 的任意两个声明:

  • If one declares E to be a variable or function, the other shall declare E as one of the same type.如果一个将 E 声明为变量或 function,则另一个应将 E 声明为同一类型之一。
  • [...] [...]

Since structured bindings are not mentioned in this list, they do not violate this rule.由于此列表中未提及结构化绑定,因此它们不违反此规则。 Similar, they do not violate One-definition rule类似,它们不违反单一定义规则

No translation unit shall contain more than one definition of any variable, function, class type, enumeration type, template, default argument for a parameter (for a function in a given scope), or default template argument.任何翻译单元都不得包含一个以上任何变量的定义,function、class 类型、枚举类型、模板、参数的默认参数(对于给定范围内的 function)或模板参数。

At least, according to what the relevant rules say, the two declarations in this example shouldn't result in any program ill-formed.至少,根据相关规则所说,这个例子中的两个声明不应该导致任何程序格式错误。 If I don't miss some other rules, Can it be considered as vague in the standard which cannot interpret why two structured binding declarations conflict with each other in this case?如果我没有错过其他一些规则,是否可以认为标准中的模糊性无法解释为什么在这种情况下两个结构化绑定声明相互冲突? This case is more underspecified in the N4861这种情况在N4861中没有详细说明

This is just a missing case in [basic.link]/11: that if one (of the two declarations) declares a structured binding, the program is ill-formed.这只是 [basic.link]/11 中的一个缺失案例:如果(两个声明中的一个)声明了结构化绑定,则程序格式错误。 (One could alternatively merely require that the other also declare a structured binding and then extend the list in [basic.def.odr]/1, but that's more complicated and suggests that it might be possible to redefine it in another translation unit.) (一个也可以只要求另一个也声明一个结构化绑定,然后在 [basic.def.odr]/1 中扩展列表,但这更复杂,并且表明可以在另一个翻译单元中重新定义它。)

You are citing text from a working draft of a post-C++20 version of the language.您引用的是该语言后 C++20 版本的工作草案中的文本。 As such, the behavior it describes is not likely implemented by any compiler currently existing.因此,它描述的行为不太可能由当前存在的任何编译器实现。 As it is a working draft, it likely contains a number of language defects and/or bugs, so trying to learn from it is not a productive activity.由于它是一个工作草案,它可能包含许多语言缺陷和/或错误,因此尝试从中学习并不是一项富有成效的活动。

All of the "correspond" language you cite is adopted from P1787, which is not part of any C++ standard actual compilers implement.您引用的所有“对应”语言均来自 P1787,它不是任何 C++ 标准实际编译器实现的一部分。 As such, compilers are providing you with the C++20 functionality, and under those rules, these clearly conflict.因此,编译器为您提供了 C++20 功能,在这些规则下,这些显然是冲突的。

There may be some defective wording in P1787, but that's expected with complex proposals and working drafts of a standard. P1787 中可能存在一些有缺陷的措辞,但对于复杂的提案和标准的工作草案,这是可以预料的。 File a defect report on it.提交一份缺陷报告。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM