推荐一个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 确实通过右值引用进行的