结构化绑定:当某些东西看起来像一个引用并且行为与引用类似时,但它不是引用

问题描述:

昨天我在SO上看到了关于结构化绑定的an interesting question
我们可以总结一下。考虑下面的例子的代码:结构化绑定:当某些东西看起来像一个引用并且行为与引用类似时,但它不是引用

#include <tuple> 
#include <type_traits> 

int main() { 
    auto tup = std::make_tuple(1, 2); 
    auto & [ a, b ] = tup; 
    // the following line won't compile for a isn't a reference 
    // static_assert(std::is_reference_v<decltype(a)>); 
} 

在这种情况下decltype(a)int(可能)因为this bullet(工作草案):

如果e是一个括号的ID-表达命名结构结合[。 ..],decltype(e)是参考类型,如结构化绑定声明的说明中给出的

Here是@Curious在感兴趣的人的评论中提供的wandbox上的一个片段。它表明实际上a不是一个参考,仅此而已。
对于原来的问题到目前为止这么好,OP问为什么它是int而不是int &该标准说看起来像一个可以接受的答案。

无论如何,我想知道为什么委员会决定如此。在一天结束时,a引用元组中的元素,我可以通过a修改该元素。换句话说,a的声明看起来就像是一个参考文献,它的行为与参考类似,但不是参考文献。

我可以忍受这一点,但我想知道背后的原因是什么。为什么decltype(a)不能简单地int &?是否有一个*能理解的有意义的理由?

+0

你可以扩展你的例子来实际证明了''是不是一个参考?对'static_assert'应该很容易,比如'std :: is_reference :: value'。 –

+0

@TobySpeight在原始问题中有您要求的示例。这就是说,你可以简单地打印'std :: is_reference_v ',它将返回0,以及'std:.is_same_v ',而'std:.is_same_v '将返回1.这很简单。 – skypjack

+1

@TobySpeight使用在线编译器https://wandbox.org/permlink/BKLeZRzPubEsPC5l? – Curious

I wrote this yesterday

decltype(x),其中x是结构化的结合,名称引用 类型的那结构结合。在类似于元组的情况下,这是由std::tuple_element返回的 类型,即使结构化绑定本身实际上始终是 引用(在这种情况下),也可能不是引用 。这有效地模拟了 绑定到其非静态数据成员具有由tuple_element返回的类型 的结构的行为,其中绑定 本身仅仅是实现细节的参考。

+0

Damnit,我昨天读过那个页面,可能在编辑之前。 – skypjack

+3

因此,简单地说,就像'some_struct.member'? –

+0

因此,'auto [a,b] = exp'和'auto&[a,b] = exp'具有非常不同的行为(对于exp的很多情况),但是在这两种情况下'decltype(a)'是相同的? – Yakk

此主题之前已经介绍过(查看结构化绑定标签),并且您正在讨论的行为甚至在第二个答案中得到解决。但是,其基本原理是在p0144r2 3.5节阐述了:

如果语法扩展到允许const/& -qualifying个人 名类型?

例如:

auto [&x, const y, const& z] = f(); // NOT proposed 

我们认为答案应该是否定的。这是一个简单的功能,用于存储 值并将名称绑定到其组件,而不是声明多个 变量。允许这样的限定将是特征蠕变, 将该特征扩展为不同的东西,即通过 声明多个变量。

如果我们想声明多重变量,我们已经有办法 拼写:

auto val = f(); 
T& x  = get<0>(val); 
T2 const y = get<1>(val); 
T3 const& z = get<2>(val); 
+2

我不认为这是相关的:问题是为什么整个结构化绑定的引用限定符不适用于这两个已声明的元素 - 并不是为什么这些元素不能单独验证。 –