为何std::pair<const T&, const U&>未正确绑定类成员引用?
为什么std::pair引用成员会绑定到错误的对象?
我尝试创建一个包含std::pair<const int&, const string&>成员的Pair类,原本期望这个pair里的引用能绑定到当前对象的num和s成员,但创建多个对象后,发现pair里的引用指向了最近构造的对象的成员,甚至出现无效值。
问题代码
#include <iostream> #include <string> #include <vector> #include <utility> #include <iomanip> using namespace std; struct Pair { int num; string s; pair<const int&, const string&> pr{make_pair(num, s)}; Pair(int n, const string& s) : num(n), s(s) {} }; ostream& operator<<(ostream& out, const Pair& p) { out << setw(2) << p.num << ", " << p.s << ": <" << p.pr.first << "," << p.pr.second << ">"; return out; } int main() { cout << string(15, '-') << " PIECEMEAL " << string(15, '-') << endl; Pair p1{1, "normal1"}; Pair p2{2, "normal2"}; cout << p1 << endl; cout << p2 << endl << endl; cout << string(15, '-') << " VECTOR " << string(15, '-') << endl; vector<Pair> v; for (int i=0; i< 5; ++i) { v.emplace_back(i, "from_vec'" + ::to_string(i) + "'"); } for(const auto & p : v) { cout << p << endl; } }
运行输出
--------------- PIECEMEAL --------------- 1, normal1: <2,normal2> 2, normal2: <1586964272,normal2> --------------- VECTOR --------------- 0, from_vec'0': <4,from_vec'4'> 1, from_vec'1': <1586964272,from_vec'4'> 2, from_vec'2': <1586964272,from_vec'4'> 3, from_vec'3': <1586964272,from_vec'4'> 4, from_vec'4': <1586964272,from_vec'4'>
问题原因
核心错误出在make_pair(num, s)的使用上:
make_pair接收的是num(int类型)和s(string类型)的值,返回的是一个临时的std::pair<int, string>对象,而非引用类型的pair。- 当用这个临时pair初始化
pr(类型为std::pair<const int&, const string&>)时,pr里的引用会绑定到临时pair的成员变量上,而不是当前Pair对象的num和s。 - 临时pair在
pr初始化完成后就会被销毁,此时pr里的引用变成悬空引用。后续构造新对象时,临时对象的内存可能被新的临时数据覆盖,就出现了引用指向最近构造对象成员或垃圾值的情况。
解决方法
直接使用std::pair的构造函数,显式绑定当前对象的成员,不要用make_pair:
struct Pair { int num; string s; pair<const int&, const string&> pr{num, s}; // 直接绑定当前对象的num和s Pair(int n, const string& s) : num(n), s(s) {} };
修改后,每个Pair对象的pr成员都会正确绑定到自身的num和s,运行输出会符合预期。
内容的提问来源于stack exchange,提问作者trozzel
相关产品推荐
相关产品推荐

