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