【问题标题】:How can I have a pair with reference inside vector?我怎样才能在向量内有一对参考?
【发布时间】:2018-05-30 16:00:37
【问题描述】:

我确实需要在 std::pairstd::vector 中使用参考 (&),但是当我尝试使用 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 << "\n";
}

这段代码演示了这个问题 - 而不是"2: 1,0,",它输出"2: -342851272,0,"(或类似的大负数)。

问题出在哪里?

【问题讨论】:

  • 你认为你为什么需要这样做?
  • @NeilButterworth 好吧,因为他们(这是学校作业)正在测试该功能并期待此回报。
  • @StoryTeller 是的,我通常会很乐意使用它,但我现在没有选择。
  • 允许使用标准库的学校作业?但不是你真正需要的部分?好吧,我猜你的作业做错了。

标签: c++ pointers vector reference unique-ptr


【解决方案1】:

由于C++14 std::make_pair被定义为

template< class T1, class T2 >
std::pair<V1,V2> make_pair( T1&& t, T2&& u );

其中V1V2 分别是std::decay&lt;T1&gt;::typestd::decay&lt;T2&gt;::type

这意味着您的 make_pair&lt;const int&amp;, int&gt; 调用并不会真正生成以引用作为其第一个元素的对(与您显然相信的相反)。他们实际上生产pair&lt;int, int&gt; 类型的临时文件。此时,您丢失了对存储在您的unique_ptr 中的原始int 对象的任何附件。

当您将这些 pair&lt;int, int&gt; 临时变量传递给 push_back 时,它们会隐式转换为 pair&lt;const int&amp;, int&gt; 类型的临时变量,这是您的向量的元素类型。通过这种机制,您可以将向量元素内的引用附加到由make_pair 生成的pair&lt;int, int&gt; 临时成员的int 成员(而不是存储在unique_ptrs 中的int 对象)。一旦临时文件到期,引用就会变质。


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

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

但您以后可能会遇到由原始引用引起的其他问题。

【讨论】:

  • 谢谢,我正在尝试直接构造,到目前为止它正在工作,(编辑:是的,插入的参考地址实际上与现在的 unique_ptr.get() 相同)你能解释一下吗为什么它确实有效?并且通过稍后的原始引用问题,它“只是”关于它们可能指向无处,而不是干扰unique_ptr 内存管理,对吧?
猜你喜欢
  • 2020-12-06
  • 2018-10-05
  • 2021-12-15
  • 1970-01-01
  • 2019-10-30
  • 2023-02-05
  • 1970-01-01
  • 2018-01-04
相关资源
最近更新 更多