如何迭代在C++中充满字符串的std :: map

cra*_*yte 62 c++ dictionary iterator stdmap std

我有以下问题涉及迭代使用定义的字符串的关联数组std::map.

-- snip --
class something 
{
//...
   private:
      std::map<std::string, std::string> table;
//...
}
Run Code Online (Sandbox Code Playgroud)

在构造函数中,我使用与字符串数据相关联的字符串键对填充表.在其他地方我有一个方法toString返回一个字符串对象,该对象包含表对象中包含的所有键和相关数据(如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());
           //....
        }
       //...
}
Run Code Online (Sandbox Code Playgroud)

当我尝试编译时,我收到以下错误:

error: "error: no match for call to ‘(std::basic_string<char,
    std::char_traits<char>, std::allocator<char> >) ()’".
Run Code Online (Sandbox Code Playgroud)

有人可以向我解释失踪的是什么,我做错了什么?hash_map在用户必须定义​​散列函数以便能够hash_mapstd::string对象一起使用的情况下,我才发现有关类似问题的一些讨论.在我的情况下也可能是类似的东西?

Tom*_*eys 73

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

...append(iter->first) rather than ...append(iter->first())
Run Code Online (Sandbox Code Playgroud)

作为一种风格问题,您不应该使用它new来创建该字符串.

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;
}
Run Code Online (Sandbox Code Playgroud)

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

for (auto& item: table) {
    ...
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*ork 19

  1. 不要写一个toString()方法.这不是Java.为您的类实现流操作符.

  2. 更喜欢使用标准算法而不是编写自己的循环.在这种情况下,std::for_each()为您想要做的事情提供了一个很好的界面.

  3. 如果你必须使用一个循环,但不打算更改数据,更喜欢const_iteratoriterator.这样,如果您意外尝试更改值,编译器将发出警告.

然后:

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));
}
Run Code Online (Sandbox Code Playgroud)

然后,当您想要打印它时,只需流式传输对象:

int main()
{
    something    bob;
    std::cout << bob;
}
Run Code Online (Sandbox Code Playgroud)

如果您确实需要对象的字符串表示,则可以使用lexical_cast.

int main()
{
    something    bob;

    std::string  rope = boost::lexical_cast<std::string>(bob);
}
Run Code Online (Sandbox Code Playgroud)

需要填写的详细信息.

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 << data.first << "=" << data.second << "\n";
         }
         private:  std::ostream& m_str;
    };
    DataMap    table;
    public:
        void something::print(std::ostream& str);
};
Run Code Online (Sandbox Code Playgroud)

  • 使用流媒体运营商是个好主意.具有签名std :: ostream&operator <<(std :: ostream&stream,std :: pair <std :: string,std :: string>&pair)的函数将允许你去cout <<*itr (2认同)