【问题标题】:structured bindings: when something looks like a reference and behaves similarly to a reference, but it's not a reference结构化绑定:当某些东西看起来像引用并且行为类似于引用,但它不是引用时
【发布时间】:2017-06-22 09:39:09
【问题描述】:

昨天我在 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 在 cmets 中为感兴趣的人提供的魔杖盒上的 sn-p。它表明实际上a 不是参考,仅此而已。
到目前为止,原始问题的效果很好,OP 询问为什么它是 int 而不是 int &amp; 并且标准说看起来是一个可以接受的答案。

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

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

【问题讨论】:

  • 您能否扩展您的示例以实际证明a 不是参考? static_assert std::is_reference&lt;decltype(a)&gt;::value 之类的应该相当容易。
  • @TobySpeight 在原始问题中有您要的示例。话虽如此,你可以简单地打印出std::is_reference_v&lt;decltype(a)&gt;,它会返回0,std:.is_same_v&lt;decltype(a), int &amp;&gt;,而std:.is_same_v&lt;decltype(a), int&gt;会返回1。这很简单。
  • @TobySpeight 使用在线编译器wandbox.org/permlink/BKLeZRzPubEsPC5l?
  • 我非常讨厌 ab 在这里不是参考
  • section 11.5.3中,有文字说“给定std​::​tuple_­element&lt;i, E&gt;​::​type指定的类型Ti,每个vi都是一个类型为“引用Ti”的变量,初始化为初始化器,如果初始化器是 lvaluervalue 引用,则引用是 *lvalue 引用;引用的类型是 Ti.* " 在我看来,这表明auto &amp; [ ] 应该声明引用...

标签: c++ language-lawyer c++17 structured-bindings


【解决方案1】:

I wrote this yesterday:

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

【讨论】:

  • 该死,我昨天读过那个页面,可能是在编辑之前。
  • 那么,简单来说就是some_struct.member?
  • 那么,auto[a,b] = expauto&amp;[a,b] = exp 有非常不同的行为(对于许多 exp 情况),但 decltype(a) 在两种情况下是相同的?
  • @Yakk 好像是这样,DanielJour 和 T.C. 的类比很好地解释了这一点,我想我现在明白了
  • @T.C.如果你写了,你能不能试着把这个解释移到页面顶部附近的某个地方?因为这使得结构化绑定实际上做的事情变得更加清晰(至少对我来说,我怀疑其他人也是如此)并且该页面上的很多内容很难理解(对于像我这样的凡人)
【解决方案2】:

这个主题之前已经介绍过(查看结构化绑定标签),您所说的行为甚至在第二个答案中得到了解决。但是,p0144r2 第 3.5 节详细说明了基本原理:

是否应该扩展语法以允许 const/&amp;-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);

【讨论】:

  • 我认为这无关紧要:问题是为什么结构化绑定上的引用限定符作为一个整体不适用于其中声明的两个元素 - 而不是为什么这些元素不能单独限定.
猜你喜欢
  • 2012-08-24
  • 2013-10-27
  • 2012-12-25
  • 1970-01-01
  • 2012-02-23
  • 1970-01-01
  • 1970-01-01
  • 2014-05-06
  • 1970-01-01
相关资源
最近更新 更多