Dav*_*one 13 c++ c++17 structured-bindings
的最新草稿结构化绑定提案(在其上的C++ 17特征是基于)的要求std::tuple_size,构件get或std::get,和std::tuple_element.以前的草稿只需要std::tuple_size和成员get或std::get.据我所知,没有讨论增加这一点,它只是出现在最终草案中.是否有令人信服的理由要求tuple_element专业化,考虑到我认为它可以作为一般实施
template<std::size_t index, typename T>
struct tuple_element {
using type = decltype(std::get<index>(std::declval<T>()));
};
Run Code Online (Sandbox Code Playgroud)
有谁知道为什么要添加此要求?
考虑一下案例:
std::tuple<int, int&>& foo();
auto& [x, y] = foo();
Run Code Online (Sandbox Code Playgroud)
什么是decltype(x)什么decltype(y)?语言功能的目标是x只是另一个名称,foo().__0并且y是另一个名称foo().__1,这意味着它们应该分别是int和int&.正如今天所说,这打包成†:
auto& __e = foo();
std::tuple_element_t<0, decltype(__e)>& x = std::get<0>(__e);
std::tuple_element_t<1, decltype(__e)>& y = std::get<1>(__e);
Run Code Online (Sandbox Code Playgroud)
而规则的工作,从而decltype(x)是它的类型x 是指,所以int.并且decltype(y)是y 指的类型,所以int&.
如果我们避免tuple_element,通过这样做:
auto&& x = std::get<0>(__e);
auto&& y = std::get<1>(__e);
Run Code Online (Sandbox Code Playgroud)
然后我们无法区分x和y,因为没有办法区分什么std::get<0>(__e)和std::get<1>(__e)做什么:两者都给予回报int&.
这也是在上述案例和普通struct结构之间增加一致性的方法:
struct C {
int i;
int& r;
};
C& bar();
auto& [a, b] = bar();
Run Code Online (Sandbox Code Playgroud)
我们希望,对于结构化绑定的目的,a并且b这里有同样的表现方式x及y存在.而a与b此不引入变量,他们只是不同的名称__e.i和__e.r.
在非参考案例中,我们无法区分不同的情况:
std::tuple<int, int&&> foo();
auto [x, y] = foo();
Run Code Online (Sandbox Code Playgroud)
在这里,我们目前通过以下方式解压:
auto __e = foo();
std::tuple_element_t<0, decltype(e)>& x = std::get<0>(std::move(__e));
std::tuple_element_t<1, decltype(e)>& y = std::get<1>(std::move(__e));
Run Code Online (Sandbox Code Playgroud)
这两个std::get调用返回的int&&,所以你可以在它们之间使用不区分auto&&......但结果tuple_element_t-是不同的int,并int&&分别.这种差异也可以在普通的结构案例中看到.
†请注意,由于CWG 2313,实际上解包发生在一个唯一命名的变量引用中,并且绑定中指定的标识符仅引用那些对象.
| 归档时间: |
|
| 查看次数: |
388 次 |
| 最近记录: |