【问题标题】:Weird behavior of std::pair second when returned from a function从函数返回时第二个 std::pair 的奇怪行为
【发布时间】:2016-06-29 11:39:26
【问题描述】:
#include<boost/unordered_map.hpp>
#include<string>
#include<iostream>
#include<boost/unordered_set.hpp>
using namespace std;

typedef boost::unordered_map<string, boost::unordered_map<string,     boost::unordered_set<string>>> nfa;
const boost::unordered_map<string, boost::unordered_set<string>>&    
get_second(const std::pair<string, 
           boost::unordered_map<string, boost::unordered_set<string>>>& p)
 {return p.second;}


int main()
{
   nfa a;
   a["A"]["0"] = {"B", "C"};
   a["A"]["1"] = {"B"};
   a["B"]["0"] = {"B"};
   a["B"]["1"] =  {"C"};
   cout << "Printing using direct reference" << endl;
   for (auto tr_table : a)
   {
     for (auto tr : tr_table.second)
      cout << tr_table.first << " " << tr.first << " " <<     tr.second.size() << endl;
  }
  cout << "Printing using function get_second" << endl;
  for (auto tr_table : a)
  {
    for (auto tr : get_second(tr_table))
      cout << tr_table.first << " " << tr.first << " " << tr.second.size() << endl;
  }
 return 0;
 }

对于相同的 unordered_map,使用 tr.second 返回正确的行数,但使用 get_second 返回没有元素的新地图元素。 这种行为的原因是什么?

我在 Ubuntu 上使用 g++ 5.3.1。

PS:使用 std::unordered_map 时的行为是相同的。

【问题讨论】:

  • 你正在复制很多地图。
  • 我并不担心继续复制,但我想了解为什么两个 for 循环的行为不同。有没有办法避免复制?
  • Visual Studio 在 in 内部循环中引发迭代器 derferencing 的调试异常。 (使用std:: 版本)。
  • 对不起,我忘了提,我在 ubuntu 上使用 g++ 5.3.1。
  • @prasannak “有没有办法避免复制?”。对其他循环使用 for( const auto&amp; tr_table : a ) 和类似的东西

标签: c++ stl unordered-map


【解决方案1】:

get_second 采用一对错误类型,带有非const 键。

因此构造了一个转换后的临时文件,并且您正在返回对该临时文件的引用。

在那之后所有的赌注都取消了。

【讨论】:

  • 我想在这个时刻指出,这个问题和混乱是由auto引起的(至少部分)。如果您首先列出类型(可能在typedef 后面)而不是允许扣除,那么您会更早地看到失败。虽然,公平地说,这里真正的罪魁祸首是隐式转换。
  • 顺便说一句,这就是我发现它的方式......因为我正在简化类型......
  • nfa::value_type 会是最好的。
  • 另一个问题是手动编写类型而不使用 map 为您提供的成员类型别名。
  • @prasannak 在这里你可以看到value_type。这是C++ standard library concept of Container。简而言之,value_type 是实际存储在容器中的内容
【解决方案2】:

您的 get_second 方法参数在 constness 方面与循环迭代器不匹配...更新如下(注意成对的 const 字符串)并且它可以工作:

get_second( const std::pair<const string,
    unordered_map<string, unordered_set<string>>>& p )

【讨论】:

    【解决方案3】:

    注意std::unordered_mapvalue_typestd::pair&lt;const Key, T&gt;(是const Key),所以你get_second()的参数是错误的。

    您只需更改为get_second(const nfa::value_type&amp; p) 即可获得正确的行为。

    【讨论】:

      猜你喜欢
      • 2021-11-19
      • 1970-01-01
      • 1970-01-01
      • 2018-02-04
      • 2015-12-28
      • 1970-01-01
      • 2020-03-24
      • 1970-01-01
      • 2020-08-17
      相关资源
      最近更新 更多