【问题标题】:What is the type of an auto const & map iterator? c++auto const & map 迭代器的类型是什么? C++
【发布时间】:2018-08-28 11:49:01
【问题描述】:

我需要修复我的一个旧项目的一些错误,我认为这是重构一些代码的最佳时机。

我有以下结构的地图:

std::map< std::string, std::map<std::string, myClass*> > ComponentMap;

某处我需要遍历一些底层子地图,我使用了以下内容:

for (std::map<std::string, myClass* >::iterator iter = ComponentMap[compNameString].begin(); iter != ComponentMap[compNameString].end(); ++iter)
{
 //some code
 if (IsComponentOfType(iter, sCOMP_PRINCIPAL))
     iter->second->GetComponentValue(date, compName, 00);
 //some more code
}

IsComponentOfType 函数具有以下声明:

bool IsComponentOfType(const std::map<std::string, myClass* >::iterator & MapIter, const sCOMPONENT_TYPE & Type)

我的问题是: 当我这样重写for循环时:

for (auto const& iter: ComponentMap[compNameString])

我收到以下编译错误:

IsComponentOfType(const std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>> &,const sCOMPONENT_TYPE &)': cannot convert argument 1 from 'const std::pair<const _Kty,_Ty>' to 'const std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>> &'

为了“使”c++11 语法起作用,我需要重写函数的第一个参数是什么类型的?

【问题讨论】:

  • auto const&amp; iter 使用该语法它不会是迭代器,它将是迭代器指向的内容,iirc 是一对 const 字符串 myClass*。 (编辑:事实上你的错误信息告诉你:cannot convert argument 1 from 'const std::pair&lt;const _Kty,_Ty&gt;'
  • 错误告诉你类型:const std::pair&lt;const _Kty,_Ty&gt;_Kty_Ty 是映射的键和值模板参数。
  • 将迭代器作为函数的参数是糟糕的设计。它应该采用值、引用或常量引用。

标签: c++ c++11 dictionary iterator


【解决方案1】:

std::map< std::string, std::map<std::string, myClass*> > ComponentMap;

for (auto const& iter: ComponentMap[compNameString]) {}

iter 的类型实际上可以推导出为std::map&lt;std::string, myClass*&gt;::value_type const&amp;,它等于std::pair&lt;std::string const, myClass*&gt; const&amp;

range-based for loop 得到的是不是迭代器,它是一个。每个值对应于您循环的容器中的一个元素。

【讨论】:

  • 在这种情况下,它不是一个值,而是一个 const 对一个值的引用。
【解决方案2】:

C++11 for 循环遍历元素。

备份并返回工作循环代码。然后在循环顶部添加行auto const&amp; elem=*iter;

接下来,逐行消除循环体中iter 的使用。确保更改每一行后代码都能编译并运行。

if (IsComponentOfType(iter, 

改成

if (IsComponentOfType(elem, 

在C++03代码中编译(修改IsComponentOfTypestd::pair&lt;std::string const, myClass*&gt; const&amp;)。

iter->second

改成

elem.second

一旦完成(和其他地方类似),将循环更改为 C++11 样式:

for (auto const& elem: ComponentMap[compNameString])

完成了。

【讨论】:

  • 来自 OP:“我的问题是:当我这样重写 for 循环时:for (auto const&amp; iter: ComponentMap[compNameString])”他们已经按照你的建议做了,这就是他们首先得到错误的原因。
  • @Borgleader Yakk 建议撤消该步骤,先执行其他步骤(包括更改 IsComponentOfType 的声明),然后再更改为 C++ for 循环,在这一点一切都应该正常工作。这个答案是一个重构配方,通过小的中间步骤将您从 A 点(旧代码,工作)带到 B 点(C++11 风格,工作),所有这些都会产生工作代码。
  • @melpomene 呵呵,我完全不清楚。
  • @borg 澄清。
【解决方案3】:

Range-based for loop:

attr(optional) for ( range_declaration : range_expression ) loop_statement

range_declaration - 命名变量的声明,其类型是 range_expression 所表示的序列元素的类型,或对该类型的引用。经常使用 auto 说明符进行自动类型推导。

由于iter 是一个值,
而不是:

iter->second->GetComponentValue(date, compName, 00);

这应该可行:

iter.second->GetComponentValue(date, compName, 00);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-19
    • 2014-09-30
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    相关资源
    最近更新 更多