我怎样才能在向量中有一对引用?
How can I have a pair with reference inside vector?
我确实需要在内部使用引用 (&
) 制作 std::pair
的 std::vector
,但是当我尝试 push_back
引用值时它在函数内部中断。调试后发现,reference的地址和unique_ptr
里面的地址不一样(但是值是一样的)。
当我不使用(这里是 foo())任何插入向量的函数时,它引用的值是正确的,但地址仍然不匹配。
#include <iostream>
#include <memory>
#include <iterator>
#include <string>
#include <vector>
void foo(std::vector<std::pair<const int&, int> >& vector,
std::unique_ptr<int>& ptr) {
vector.push_back(std::make_pair<const int&, int>(*ptr, 11));
}
int main() {
std::vector<std::pair<const int&, int> > v;
std::unique_ptr<int> i = std::make_unique<int>(1);
std::unique_ptr<int> b = std::make_unique<int>(0);
foo(v, i);
v.push_back(std::make_pair<const int&, int>(*b, 10));
std::cout << v.size() << ": ";
for (auto x : v) {
std::cout << x.first << ",";
}
std::cout << "\n";
}
此代码演示了问题 - 而不是 "2: 1,0,"
它输出 "2: -342851272,0,"
(或首先是类似的大负数)。
问题出在哪里?
因为 C++14 std::make_pair
定义为
template< class T1, class T2 >
std::pair<V1,V2> make_pair( T1&& t, T2&& u );
其中 V1
和 V2
分别是 std::decay<T1>::type
和 std::decay<T2>::type
。
这意味着您的 make_pair<const int&, int>
调用并没有真正生成以引用作为第一个元素的对(与您显然相信的相反)。他们实际上生产 pair<int, int>
类型的临时文件。此时,您将失去存储在 unique_ptr
中的原始 int
对象的所有附件。
当您将这些 pair<int, int>
临时对象传递给 push_back
时,它们会隐式转换为 pair<const int&, int>
类型的临时对象,这是您的向量的元素类型。通过这种机制,您可以将向量元素内的引用附加到 make_pair
生成的那些 pair<int, int>
临时对象的 int
成员(而不是存储在 unique_ptr
中的 int
对象).一旦临时文件过期,引用就会变质。
在这种情况下,您可以通过完全避免 make_pair
并简单地直接构造适当类型的 std::pair
对象来消除这个特定问题,例如
vector.push_back(std::pair<const int&, int>(*ptr, 11));
但您以后可能会 运行 遇到由原始引用引起的其他问题。
我确实需要在内部使用引用 (&
) 制作 std::pair
的 std::vector
,但是当我尝试 push_back
引用值时它在函数内部中断。调试后发现,reference的地址和unique_ptr
里面的地址不一样(但是值是一样的)。
当我不使用(这里是 foo())任何插入向量的函数时,它引用的值是正确的,但地址仍然不匹配。
#include <iostream>
#include <memory>
#include <iterator>
#include <string>
#include <vector>
void foo(std::vector<std::pair<const int&, int> >& vector,
std::unique_ptr<int>& ptr) {
vector.push_back(std::make_pair<const int&, int>(*ptr, 11));
}
int main() {
std::vector<std::pair<const int&, int> > v;
std::unique_ptr<int> i = std::make_unique<int>(1);
std::unique_ptr<int> b = std::make_unique<int>(0);
foo(v, i);
v.push_back(std::make_pair<const int&, int>(*b, 10));
std::cout << v.size() << ": ";
for (auto x : v) {
std::cout << x.first << ",";
}
std::cout << "\n";
}
此代码演示了问题 - 而不是 "2: 1,0,"
它输出 "2: -342851272,0,"
(或首先是类似的大负数)。
问题出在哪里?
因为 C++14 std::make_pair
定义为
template< class T1, class T2 >
std::pair<V1,V2> make_pair( T1&& t, T2&& u );
其中 V1
和 V2
分别是 std::decay<T1>::type
和 std::decay<T2>::type
。
这意味着您的 make_pair<const int&, int>
调用并没有真正生成以引用作为第一个元素的对(与您显然相信的相反)。他们实际上生产 pair<int, int>
类型的临时文件。此时,您将失去存储在 unique_ptr
中的原始 int
对象的所有附件。
当您将这些 pair<int, int>
临时对象传递给 push_back
时,它们会隐式转换为 pair<const int&, int>
类型的临时对象,这是您的向量的元素类型。通过这种机制,您可以将向量元素内的引用附加到 make_pair
生成的那些 pair<int, int>
临时对象的 int
成员(而不是存储在 unique_ptr
中的 int
对象).一旦临时文件过期,引用就会变质。
在这种情况下,您可以通过完全避免 make_pair
并简单地直接构造适当类型的 std::pair
对象来消除这个特定问题,例如
vector.push_back(std::pair<const int&, int>(*ptr, 11));
但您以后可能会 运行 遇到由原始引用引起的其他问题。