推薦一個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 確實通過右值引用進行的