如何在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) { ... }
-
不要写一个
toString()
方法。 这不是Java。 为你的课程实现stream操作符。 -
更喜欢使用标准algorithm来编写自己的循环。 在这种情况下,
std::for_each()
为你想要做的事提供了一个很好的接口。 -
如果您必须使用循环,但不打算更改数据,则
const_iterator
于iterator
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 。 first
和second
的值不是函数,它们是variables。
更改:
iter->first()
至
iter->first
同上 – iter->second
。
iter->first
和iter->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副本的内存之后进行的。
- EF映射和元数据信息找不到EntityType错误
- 如何强制Hibernate返回date为java.util.Date而不是Timestamp?
- 我怎样才能快速估计两个(纬度,经度)点之间的距离?
- 什么algorithm在地图上计算从点A到点B的方向?
- 在LeafletJS中使用自定义地图图像切片?
- Server.MapPath(“。”),Server.MapPath(“〜”),Server.MapPath(@“\”),Server.MapPath(“/”)。 有什么不同?
- 什么是实现嵌套字典的最佳方式?
- 在MySQL数据库中存储纬度/经度时使用的理想数据types是什么?
- 高性能并发MultiMap Java / Scala