如何在C ++中遍历一个充满string的STL映射

我有以下问题相关迭代使用std :: map定义的string的关联数组。

-- snip -- class something { //... private: std::map<std::string, std::string> table; //... } 

在构造函数中,我使用与string数据关联的string键来填充表。 在其他地方,我有一个toString方法,它返回一个string对象,该对象包含表格对象中包含的所有关键字和关联数据(如key =数据格式)。

 std::string something::toString() { std::map<std::string, std::string>::iterator iter; std::string* strToReturn = new std::string(""); for (iter = table.begin(); iter != table.end(); iter++) { strToReturn->append(iter->first()); strToReturn->append('='); strToRetunr->append(iter->second()); //.... } //... } 

当我试图编译时,我得到以下内容

错误:“错误:调用不匹配”(std :: basic_string,std :: allocator>)()'“。

有人可以向我解释什么是错过的,我做错了什么? 在hash_map的情况下,我只find了一些有关类似问题的讨论,其中用户必须定义​​一个哈希函数来使用hash_map和std :: string对象。 可能是类似的东西在我的情况?

谢谢!

你的主要问题是你在迭代器中调用first()方法。 你打算做的是使用名为first的属性:

 ...append(iter->first) rather than ...append(iter->first()) 

就风格而言,你不应该使用new来创build这个string。

 std::string something::toString() { std::map<std::string, std::string>::iterator iter; std::string strToReturn; //This is no longer on the heap for (iter = table.begin(); iter != table.end(); ++iter) { strToReturn.append(iter->first); //Not a method call strToReturn.append("="); strToReturn.append(iter->second); //.... // Make sure you don't modify table here or the iterators will not work as you expect } //... return strToReturn; } 

编辑: facildelembrar指出(在评论中),现代C ++中,你现在可以重写循环

 for (auto& item: table) { ... } 
  1. 不要写一个toString()方法。 这不是Java。 为你的课程实现stream操作符。

  2. 更喜欢使用标准algorithm来编写自己的循环。 在这种情况下, std::for_each()为你想要做的事提供了一个很好的接口。

  3. 如果您必须使用循环,但不打算更改数据,则const_iteratoriterator const_iterator 。 这样,如果你不小心尝试和改变这些值,编译器会警告你。

然后:

 std::ostream& operator<<(std::ostream& str,something const& data) { data.print(str) return str; } void something::print(std::ostream& str) const { std::for_each(table.begin(),table.end(),PrintData(str)); } 

那么当你想要打印它时,只需要stream式传输对象:

 int main() { something bob; std::cout << bob; } 

如果实际需要对象的string表示forms,则可以使用lexical_cast

 int main() { something bob; std::string rope = boost::lexical_cast<std::string>(bob); } 

需要填写的细节。

 class somthing { typedef std::map<std::string,std::string> DataMap; struct PrintData { PrintData(std::ostream& str): m_str(str) {} void operator()(DataMap::value_type const& data) const { m_str << value.first << "=" << value.second << "\n"; } private: std::ostream& m_str; }; DataMap table; public: void something::print(std::ostream& str); }; 

改变你的追加电话说

 ...append(iter->first) 

 ... append(iter->second) 

另外,线路

 std::string* strToReturn = new std::string(""); 

在堆上分配一个string。 如果你打算实际返回一个指向这个dynamic分配的string的指针,返回值应该改为std :: string *。

或者,如果您不想担心在堆上pipe理该对象,请将本地声明更改为

 std::string strToReturn(""); 

并更改“附加”调用使用参考语法…

 strToReturn.append(...) 

代替

 strToReturn->append(...) 

请注意,这将构build堆栈中的string,然后复制到返回variables中。 这具有性能影响。

请注意,解引用std :: map :: iterator的结果是std :: pair 。 firstsecond的值不是函数,它们是variables。

更改:

 iter->first() 

 iter->first 

同上 – iter->second

iter->firstiter->second是variables,你试图把它们作为方法调用。

使用:

 std::map<std::string, std::string>::const_iterator 

代替:

 std::map<std::string, std::string>::iterator 

在C + + 11可以使用

 for ( auto iter : table ) { key=iter->first(); value=iter->second(); } 

另一个有价值的优化是STL string类的c_str()成员,它返回一个可以作为LPCTSTR传递的不可变的以NULL结尾的string,例如,传递给一个自定义函数,该函数需要一个LPCTSTR。 尽pipe我没有通过析构函数来确认它,但我怀疑这个string类是在创build副本的内存之后进行的。