如何在向量内部引用一对?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在向量内部引用一对?相关的知识,希望对你有一定的参考价值。

我真的需要在std::vector中加入std::pair并引用(&),但是当我尝试使用push_back参考值时,它会在函数内部打破。调试后我发现,引用的地址与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 << "
";
}

此代码演示了问题 - 而不是"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 );

其中V1V2分别是std::decay<T1>::typestd::decay<T2>::type

这意味着你的make_pair<const int&, int>调用并不真正产生带有引用的对作为它们的第一个元素(与你显然相信的相反)。他们实际上生产pair<int, int>类型的临时工。此时,您将丢失对存储在int中的原始unique_ptr对象的任何附件。

当你将这些pair<int, int> temporaries传递给push_back时,它们会被隐式转换为pair<const int&, int>类型的临时值,这是你的向量元素类型。通过这种机制,你可以将你的vector元素中的引用附加到int生成的那些pair<int, int>临时值的make_pair成员(而不是存储在ints中的unique_ptr对象)。一旦临时过期,引用就会变坏。


在这种情况下,您可以通过完全避免make_pair并简单地直接构造适当类型的std::pair对象来消除这个特定问题,例如

vector.push_back(std::pair<const int&, int>(*ptr, 11));

但是你可能会遇到后来由原始引用引起的其他问题。

以上是关于如何在向量内部引用一对?的主要内容,如果未能解决你的问题,请参考以下文章

Android 我应该在异步任务中将片段作为弱引用传递吗?

通过引用传递向量内联

有没有办法访问/取消引用并查找存储在双指针向量中的元素的值? [关闭]

如何通过引用推送向量?

底部导航 如何从片段内部更改片段

如何在 FragmentPagerAdapter 中添加片段标签以便稍后引用片段?