当前位置: 首页 > 知识库问答 >
问题:

为什么结构化绑定是根据唯一命名的变量定义的?

龙焱
2023-03-14

为什么结构化绑定是通过一个唯一命名的变量和所有模糊的“name is bind to”语言定义的?

我个人认为结构化绑定的工作原理如下。给定一个结构:

struct Bla
{
    int i;
    short& s;
    double* d;
} bla;

以下内容:

cv-auto ref-operator [a, b, c] = bla;

大致相当于

cv-auto ref-operator a = bla.i;
cv-auto ref-operator b = bla.s;
cv-auto ref-operator c = bla.d;

数组和元组的等价展开式。但显然,这太简单了,而且有所有这些模糊的特殊语言用来描述需要发生的事情。

很明显,我遗漏了一些东西,但确切的情况是什么,一个定义良好的扩展,比如说,折叠表达式,在标准语言中读起来要简单得多?

似乎结构化绑定定义的变量的所有其他行为实际上都遵循了我认为用来定义这个概念的简单扩展“规则”。

共有2个答案

单于承
2023-03-14

似乎结构化绑定定义的变量的所有其他行为实际上都遵循了我认为用来定义这个概念的简单扩展“规则”。

有点像。除了扩展不是基于右边的表达式,它是基于引入的变量。这其实很重要:

X foo() {
    /* a lot of really expensive work here */
   return {a, b, c};
}

auto&& [a, b, c] = foo();

如果扩展到:

// note, this isn't actually auto&&, but for the purposes of this example, let's simplify
auto&& a = foo().a;
auto&& b = foo().b;
auto&& c = foo().c;

它不仅效率极低,在许多情况下也可能是错误的。例如,想象一下如果foo()被实现为:

X foo() {
    X x;
    std::cin >> x.a >> x.b >> x.c;
    return x;
}

因此,它扩展为:

auto&& e = foo();
auto&& a = e.a;
auto&& b = e.b;
auto&& c = e.c;

这实际上是确保所有绑定都来自同一个对象而没有任何额外开销的唯一方法。

数组和元组的等价展开式。但显然,这太简单了,而且有所有这些模糊的特殊语言用来描述需要发生的事情。

有三种情况:

  1. 数组。每个绑定都像是对相应索引的访问。
  2. 类似元组。每个绑定都来自对std::的调用

假设,#1和#2可以合并(可以将元组机制添加到原始数组中),但是不这样做可能会更有效。

措辞(IMO)中的大量复杂性来自于处理价值类别。但不管其他东西是如何指定的,你都需要它。

傅新
2023-03-14

结构化绑定的存在是为了在一种语言中允许多个返回值,这种语言不允许函数解析为多个值(因此不会干扰C ABI)。这意味着无论使用什么语法,编译器最终都必须存储实际的返回值。因此,该语法需要一种方式来准确讨论如何存储该值。由于C在存储方式(作为引用或值)上有一定的灵活性,结构化绑定语法需要提供同样的灵活性。

因此,auto

其次,我们不想用这个特性影响性能。这意味着引入的名称永远不会是主对象的子对象的副本。它们必须是引用或实际的子对象本身。这样,人们就不会担心使用结构化绑定对性能的影响;它是纯语法糖。

第三,系统被设计为处理用户定义的对象和所有公共成员的数组/结构。在用户定义对象的情况下,“名称绑定到”一个真正的语言引用,调用的结果得到

对于数组/公共结构,“名称绑定到”不是引用的东西。这些被完全像您键入<代码>值[2]或<代码>value.member_name一样对待。对这些名称执行<代码>Dectype不会返回引用,除非未打包的成员本身是引用。

通过这种方式,结构化绑定仍然是纯粹的语法糖:它以对该对象可能最有效的方式访问该对象。对于用户定义的类型,这就是对每个子对象调用一次get,并存储对结果的引用。对于其他类型,它使用的名称类似于数组/成员选择器。

 类似资料:
  • 在该示例中,标识符和之间的相应区别是什么?据我所知,结构绑定中的也有一个引用类型,但是为什么为它指明了一个非引用类型呢?

  • 我正在学习结构化绑定声明。我的理解是,

  • 在[dcl.struct.bind]9.6.4中,当初始值设定项是带有

  • 我一直在编写一组类来允许一个简单的类似python的-函数。下面的片段(几乎)和预期的一样工作。然而,两个变量和不是。 我一直在使用gcc 7.3.0。以下是MCVE:

  • 简短版本: 我希望能够将结构转换为元组。至少是那种类型。在下面的代码中,convertToTuple函数不起作用,因为可变参数不能用于结构化绑定(据我所知)。关键是:自动 基本上,我需要的是一种将自定义结构的类型转换为元组的方法,元组包含结构中的所有类型。例如: 具体问题: 我想创建一个模板函数,它将一个类型或一个类型列表作为模板参数,并生成一个纹理列表,每个纹理包含一个项目。另一个函数可以对纹理

  • 2、结构类型变量的定义 在定义某个结构类型后,程序员就可以说明该结构类型的内存变量。它的说明形式与前面介绍的简单数据类型的变量说明基本上一致。其定义格式如下: [变量名] 结构名 <[字段值表]>