20200216 pair 和 tuple 對與 && 右值引用體驗引申

推薦一個C++在線編輯器支持C++17 在線編譯器網站

問題代碼:

/*本人在 C++17 測試
    分別嘗試以下代碼
*/
/* 第一種 */
std::pair<int, int&&> t; //提示錯誤沒有提供值

/* 第二種 */
int&& k = 10;
std::pair<int, int&&> t1 = std::make_pair(10, k); 
//編譯通過運行錯誤,嘗試提取值
std::cout << "1: " << std::get<0>(t1) << " 2: " << std::get<1>(t1) << std::endl;
//輸出 1: 10 2: 0

/* 第三種 */
int&& k = 11;
std::tuple<int, int&&> t2 = std::make_tuple(10, k);//正常

這裏不探討爲何 tuple 可以但是 pair 不可以實現功能

 

提問1

1 爲何用 pair 去引用一個右值會失敗

2 pair 到底如何工作


解決嘗試:

知識點: 建議查看其他說明

pair 是一種類似可以存儲兩個值的結構體,而 tuple 是 pair 的一種拓展支持存儲多個值的結構

make_pair 採用的是右值引用

1 pair<int, int&>  or pair<int, int&&> 無法編譯的原因

很簡單的道理,int& a; 是非法的,引用不像指針擁有自己的地址,所以它不可以單處存在的

 

2 std::pair<int, int&&> t1 = std::make_pair(10, k); 可以編譯執行出錯原因

首先得說到 bind 和 std::reference_wrapper

void print_num(int i, int b)
{
    std::cout << i << "  XX  " << b << '\n';
}

int main() {

    int k = 10;
    auto f1 = std::bind(print_num, std::ref(k), k);
    k = 11;
    f1(10);

    return 0;
}
//11 XX 10

是因爲 bind 過程爲了保證右值引用生存期,bind 在構造過程自身複製了一份值,而 std::ref(k) 本質就是產生一個 std::reference_wrapper,這是一個容器用於確保所引用的值存在(差異部分看上一篇文章)

所以大家可以自行測試,pair 和 tuple 應該也是通過構造函數複製了一份值以確保在 pair 和 tuple 生存期間所引用的對象是存在的,只有爲何 pair 不可以行 tuple 可以行,沒有具體深入研究,期待大神回覆

//pair tuple 構造方式驗證
    int k = 10;
    auto f1 = std::make_pair(k,k);
    k = 11;

//但是通過閱讀源碼可知, make_pair 確實通過右值引用進行的

 

 

 

發佈了125 篇原創文章 · 獲贊 27 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章