Re: [問題] C++17 Structured binding 型別無法理解
※ 引述《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的時候可以把對型態的依賴更進一步抽掉
以此來做更強的抽象才存在的,而他為了做到這件事的代價就是可讀性
所以不要拿語法糖的角度來質疑他的可讀性或型態不明確之類的
因為"型態不用明確"這件事正是他的存在意義。
:
: 討論一下~
:
: 謝謝
:
:
:
:
: --
: ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 27.242.129.39 (臺灣)
: ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1561230037.A.5C6.html
: 推 suhorng: 因為 k, v 的 type 要查 map 的 iterator 指向什麼呀 06/23 05:52
: → suhorng: for-range 轉成 for + begin/end, 然後 map 的 06/23 05:52
: 推 RishYang: key是const是map的性質 06/23 05:54
: → suhorng: value_type 是 std::pair<const Key, T>, 所以自然由 06/23 05:55
: → suhorng: auto& [k,v] = *it 知道 k 是 const 06/23 05:56
: → RishYang: pair<const K, T> 06/23 05:56
: → RishYang: tuple<Types&...> tie( Types&... args ) 06/23 06:04
: → lovejomi: 晚點理解一下 但意思是我無法馬上從code一眼看出型別 這 06/23 12:12
: → lovejomi: 樣好嗎? 06/23 12:12
: → lovejomi: 而且2. 我寫了const 竟然沒用,感覺很容易誤會 06/23 12:13
: 推 Fenikso: 我覺得這有一半是tie的問題.. 06/23 13:36
: → Fenikso: 2的a是const ref to int, 不是ref to const int 06/23 13:36
: → Fenikso: x 打錯 06/23 13:37
: 噓 hsnuyi: 先搞懂map是啥 06/23 16:16
: 推 suhorng: 我查你貼的連結, 提到 cv-auto 的地方在 array type A 06/23 16:24
: → suhorng: 那裡, 所以看來是用到 array 上的時候才看得出來? 06/23 16:28
: → suhorng: 我猜 const 不是加到 [???,???,...] 裡面的 identifier 06/23 16:29
: → suhorng: 所以才會乍看之下沒有效 06/23 16:29
: → lovejomi: key是const 但我如果是by value copy 他不該保留const 06/23 16:32
: → lovejomi: 吧? 06/23 16:32
: → suhorng: 可是看他 case 2 寫的, 不管前面有沒有 cv 或不管有沒有 06/23 16:43
: → suhorng: &, && 都是 "reference to std::tuple_element<i, E>::ty 06/23 16:43
: → lovejomi: @fenikso: const ref 沒這種東西吧?一般語法也寫不出in 06/23 16:44
: → lovejomi: t &const foo; 還是這裡有什麼高深原理? 06/23 16:44
: → RishYang: map與pair都不是array type 06/23 18:25
: → RishYang: 所以不會copy行為 06/23 18:25
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 123.193.54.11 (臺灣)
※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1561295999.A.1E3.html
※ 編輯: sarafciel (123.193.54.11 臺灣), 06/23/2019 21:29:12
※ 編輯: sarafciel (123.193.54.11 臺灣), 06/23/2019 21:30:06
推
06/23 21:51,
6年前
, 1F
06/23 21:51, 1F
→
06/23 21:51,
6年前
, 2F
06/23 21:51, 2F
→
06/23 21:51,
6年前
, 3F
06/23 21:51, 3F
對 細節上是還有這一步沒錯XD
感謝指正
推
06/24 14:14,
6年前
, 4F
06/24 14:14, 4F
※ 編輯: sarafciel (210.242.163.170 臺灣), 06/24/2019 14:57:14
推
06/24 22:26,
6年前
, 5F
06/24 22:26, 5F
是的 你得到他了
※ 編輯: sarafciel (210.242.163.170 臺灣), 06/25/2019 16:11:09
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 2 之 3 篇):
C_and_CPP 近期熱門文章
PTT數位生活區 即時熱門文章
33
68