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

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(){
}

在这个例子中,all compilers 给出了一个错误,即#2 中的 x 与在#1 中引入的冲突。但是,IIUC,post-C++20 工作草案标准中没有任何规则可以解释是什么原因。

首先,在我看来,#2 的声明和#1 的声明声明了同一个实体。它们对应于: basic.scope#scope-3

Two declarations correspond if they (re)introduce the same name, both declare constructors, or both declare destructors, unless

[...]

他们根据 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

  • they appear in the same translation unit, or
  • [...]

因此,到目前为止,它们声明了相同的实体,根据 basic.scope#scope-4

不应将它们视为潜在冲突

Two declarations potentially conflict if they correspond and cause their shared name to denote different entities([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]).

由于它们表示相同的实体,如前所述,它们不会发生潜在冲突。

他们仍然没有违反这条规则:
basic.link#11

For any two declarations of an entity E:

  • If one declares E to be a variable or function, the other shall declare E as one of the same type.
  • [...]

由于此列表中未提及结构化绑定,因此它们不违反此规则。类似的,他们不违反一个定义规则

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.

至少,根据相关规则的规定,这个例子中的两个声明不应该导致任何程序格式错误。如果我没有错过其他一些规则,是否可以将其视为标准中的含糊不清,无法解释为什么在这种情况下两个结构化绑定声明相互冲突?这种情况在 N4861

中更不明确

您引用的文本来自该语言的 post-C++20 版本的工作草案。因此,它描述的行为不太可能由当前存在的任何编译器实现。由于它是一个 工作 草稿,它可能包含一些语言缺陷 and/or 错误,因此尝试从中学习是没有成效的 activity.

您引用的所有“对应”语言均来自 P1787,它不是任何 C++ 标准实际编译器实现的一部分。因此,编译器为您提供 C++20 功能,并且在这些规则下,这些显然是冲突的。

P1787 中可能存在一些措辞缺陷,但对于复杂的提案和标准的工作草案而言,这是意料之中的。提交缺陷报告。

这只是 [basic.link]/11 中遗漏的情况:如果(两个声明之一)声明结构化绑定,则程序格式错误。 (一个也可以只要求另一个也声明一个结构化绑定,然后扩展 [basic.def.odr]/1 中的列表,但这更复杂,并且建议可以在另一个翻译单元中重新定义它。)