【问题标题】:Structured bindings implementation underground and std::tuple地下和 std::tuple 的结构化绑定实现
【发布时间】:2016-09-29 07:01:27
【问题描述】:

这是真的吗,clang 中的structured bindings(我使用最近构建的clang version 4.0.0 (trunk 282683))是使用来自<tuple> 的一些东西实现的,比如大括号初始化列表可能使用来自<initializer_list> 的东西?

我写了一些简单的代码只是为了玩一些latest features implemented

struct S { int a; char b; double c; };
auto [a, b, c] = S{1, '2', 3.0};
using A = decltype(a);
using A = int;
using B = decltype(b);
using B = char;
using C = decltype(c);
using C = double;

到目前为止一切都很好,但是当我在auto 之前添加const 限定符时:

struct S { int a; char b; double c; };
const auto [a, b, c] = S{1, '2', 3.0};
using A = decltype(a);
using A = int const;
using B = decltype(b);
using B = char const;
using C = decltype(c);
using C = double const;

我收到一个奇怪的错误描述:

In file included from /home/user/test/main.cpp:1:
In file included from /home/user/test/./test.hpp:4:
In file included from /usr/local/bin/../include/c++/v1/utility:193:
/usr/local/bin/../include/c++/v1/__tuple:29:14: fatal error: implicit instantiation of undefined template 'std::__1::tuple_size<S>'
    : public tuple_size<_Tp> {};
             ^
/home/user/test/main.cpp:110:16: note: in instantiation of template class 'std::__1::tuple_size<const S>' requested here
    const auto [a, b, c] = S{1, '2', 3.0};
               ^
/usr/local/bin/../include/c++/v1/__tuple:25:50: note: template is declared here
template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_size;
                                                 ^

即与意外包含的&lt;tuple&gt; 有交互。

我知道结构化绑定在 clang 中部分实现,但不管怎样,有趣的是 &lt;tuple&gt; 可能与它们有什么关系?

我应该包含&lt;tuple&gt; 以使用结构化绑定吗?

补充:

autoauto &amp;auto &amp;&amp; 有效,但 auto constauto const &amp; 无效。

【问题讨论】:

  • 使用std::tie 实现对我来说很自然...
  • @W.F.另一种方法是内置功能。
  • 我的意思是底层实现 :) 但我知道它不能回答你的问题......
  • LWG 2770。您可以期望在 C++17 发布之前修复此问题。
  • @W.F. tie 对我来说完全不自然,但无论如何。

标签: c++ clang c++17 stdtuple structured-bindings


【解决方案1】:

是的,结构化绑定使用tuple_sizetuple_element 作为自定义点。大致的基本规则是,

  1. 首先处理内置数组;
  2. 然后检查tuple_size&lt;T&gt;::value;
  3. 如果失败,则检查该类是否具有所有公共数据成员。

要使第 2 步可靠运行,tuple_size 需要对 SFINAE 友好,但 tuple_size&lt;cv T&gt; 目前不需要对 SFINAE 友好。因此the bug

【讨论】:

  • 有趣的是,它看起来像是一种基于 SFINAE 的算法的等效(伪)代码(就像一个存在于范围 for 循环中的代码)。为什么如果不包含&lt;tuple&gt;,这里就没有硬错误?真奇怪。因为如果没有符号std::tuple_size,那么这里肯定应该有硬错误,但事实并非如此。而违反tuple_size&lt;cv T&gt; 的 SFINAE 友好性会产生硬错误。
  • @Orient 这是一种特殊的核心语言结构;它不必遵守(正常)SFINAE 规则。并且可以说在缺少tuple_size 时不会触发硬错误是有道理的,因为独立实现根本不需要tuple_size
猜你喜欢
  • 1970-01-01
  • 2017-04-02
  • 2014-07-01
  • 2019-01-01
  • 1970-01-01
  • 2011-05-01
  • 1970-01-01
  • 2019-06-15
相关资源
最近更新 更多