Re: [问题] C++17 Structured binding 型别无法理解

楼主: sarafciel (Cattuz)   2019-06-23 21:19:56
※ 引述《lovejomi (JOMI)》之铭言:
: 标题: [问题] C++17 Structured binding 型别无法理解
: 时间: Sun Jun 23 03:00:34 2019
:
: 最近会看到一些c++17语法 想说来研究一下
:
: https://en.cppreference.com/w/cpp/language/structured_binding
:
: 网络上介绍的文章许多 但都完全只是"介绍" 我实际上遇到一些怪异的型别推导结果
:
: 完全无法归纳规则 可能变成 知道可以用 但不敢乱用....
:
: 也许cppref 有介绍的很完整但我实在是看不太懂他表达的
:
: 举几个例子
:
:
: 1. 这属于网页上的case几?我不知道....
:
: std::map<int, int> m;
: for (auto& [k, v] : m) {
: k = 123;
: }
:
: k 是const& 变成不能改 ??? why....
:
: 好那我
:
: std::map<int, int> m;
: for (auto [k, v] : m) {
: k = 123;
: }
: k是const int....哪来的const....
:
推文讲得很清楚了 map的key就是自带const
auto [k , v] : m 这行在传递的型态实际上是std::pair<const int , int>
std::pair可以被tuple_size当型态参数吃,所以是cppreference里提到的第二种case
会用tuple的方式做绑定,中括号外的cv跟reference不影响k跟v的型态
所以上面两个型态都是const int
: 2.
: int a = 1, b = 2;
: const auto& [x, y] = std::tie(a, b);
: x = 5566;
:
: 一脸就是const! 但竟然x是 int&.....可以改 why....+2
一脸个头啦
:
: 好那我
: auto [z, w] = std::tie(a, b);
: z = 123;
: 我什么都不加....乍看就是int
: z竟然是int&....我不小心改到了a.....
: 这我可能还可以理解 他会去decltype(z) 结果是int& 但实在不好读也很容易误用
1.拿出你的google,搜寻std::tuple source
2.点进去gnu给的std::tuple source ,然后把std::tie挖出来,你就可以看到:
template<typename... _Elements>
inline tuple<_Elements&...>
tie(_Elements&... __args)
{ return tuple<_Elements&...>(__args...); }
注意templates里面的型态参数跟回传的tuple差一个&
所以等号右边的型态就已经是std::tuple<int & , int &>了
这个也是cppreference的case 2,基本可以把等号左边当作是std::tuple
而外围的cv跟reference是在描述这个std::tuple
所以像const auto& [x, y] = std::tie(a, b)这种句子几乎等义于
const std::tuple<T1 , T2> & temp = std::tie(a, b);
T1跟T2取决于std::tie回传的型态
而x跟y分别代表tuple的get<0>跟get<1>,跟你外围加的const和ref一点关系都没有
要验证这件事情也很简单,你右边丢的东西是一个右值
所以你现在把左边的const拿掉来接这个右值看看,我敢跟你担保编译器会报错
:
:
:
:
: 还有很多看不是很懂...
:
: 总觉得找不到可以简单记忆的规则 连VC鼠标移过去显示的型态也是错的....
:
:
:
: 请问版上有人能通透理解这些规则吗@@
:
:
: 不然我还是觉得写17以前写法
:
: for (const auto& p : map) 我可以明确知道他在写什么好懂许多
因为你把auto当语法糖看了
或者这样讲好了
auto x = y;
Q:请问这行code在干嘛?
A:这个问题没有人答得出来,我自己都答不出来,
我甚至连这行code编译器给不给过我都不知道,因为我根本没有给y的型态。
也就是说这行程式码是完全依赖于y是什么型态在做事的,它本身的资讯含量非常的少
所以很多人会说除非你很清楚auto在接的东西会怎么运作,不然尽量少用它
而就你发问的这几个例子来讲,我想你其实连等号右边在做什么事恐怕都没有很清楚
那更不用讲cppreference那一页里面那些case by case是在处理什么东西的了
再来说说语法糖这件事。
auto在c++存在的目的并不是语法糖,尽管他有这个功能没错
auto是为了在写template的时候可以把对型态的依赖更进一步抽掉
以此来做更强的抽象才存在的,而他为了做到这件事的代价就是可读性
所以不要拿语法糖的角度来质疑他的可读性或型态不明确之类的
因为"型态不用明确"这件事正是他的存在意义。
:
: 讨论一下~
:
: 谢谢
:
:
:
:
:
作者: Fenikso (薪水小偷)   2019-06-23 21:51:00
"跟你外围加的const和ref一点关系都没有" 严格来说是有啦temp是const, get<0>(temp)会走到有const的overload,回传的type也会多一个const, 只是那个const刚好被消掉
作者: TitanEric (泰坦)   2019-06-24 14:14:00
专业推
作者: chrisdar   2019-06-24 22:26:00
const int& tt = 5; // 同理把 const 拿掉就编不过了

Links booklink

Contact Us: admin [ a t ] ucptt.com