21

昨天我在这里看到了一个关于结构化绑定的有趣问题。
我们可以总结如下。考虑下面的示例代码:

#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可能)是因为这个项目符号(工作草案):

ife是命名结构化绑定 [...] 的无括号 id 表达式,decltype(e)是结构化绑定声明规范中给出的引用类型

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

无论如何,我想知道委员会为什么会这样决定。归根结底,a指的是元组中的一个元素,我可以通过a. 换句话说,声明a看起来像一个引用,它的行为类似于引用,但它不是引用。

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

4

2 回答 2

11

我昨天写了这个

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

于 2017-06-22T10:29:42.590 回答
-1

该主题之前已涵盖(查看结构化绑定标签),您所谈论的行为甚至在第二个答案中得到解决。但是,原理在p0144r2第 3.5 节中详细说明:

是否应该扩展语法以允许const/&限定单个名称的类型?

例如:

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);
于 2017-06-22T10:31:50.063 回答