简体   繁体   English

将迭代器添加到泛型类中的泛型容器:如何

[英]getting an iterator to a generic container inside a generic class: HOW TO

This comes from a larger context, however I have stripped alot of code to simplify the question. 这来自更大的上下文,但是我剥离了很多代码以简化问题。 If you feel I have left anything out please let me know. 如果您觉得我遗漏了任何东西,请告诉我。

Lets say you have a template class defined as: 假设您有一个定义为的模板类:

#include <map>
#include <vector>
#include <string>
#include <fstream>
#include <iostream>
#include <iterator>
#include <algorithm>
template <class key, class container, class container_type>
class file_to_map
{
public:
  file_to_map()
  {
    m_file = "";
  }

  file_to_map(std::string file)
  {
    m_file = file;
  }

  ~file_to_map()
  {
  }

  std::map<key, container>& get_map()
  {
    return m_map;
  }

  void set_file(const std::string file)
  { 
    m_file = file;
  }

  void insert_into_map(key insert, container_type value)
  {
    m_map[insert].insert(value);
  }

  friend std::ostream& operator<< (std::ostream &out, file_to_map<key, container, container_type> &obj)
  {
    typedef typename std::map<key, container>::const_iterator mapItr;
    mapItr mbi = obj.m_map.begin();
    mapItr emi = obj.m_map.end();
    while (mbi != emi) {
      out << " -- " << mbi->first << " -- " << std::endl;
      container::iterator cbi;
      ++mbi;
    }
    return out;
  }

  friend std::istream& operator>> (std::ifstream &in, file_to_map<key, container, container_type> &obj)
  {
    if (in.is_open())
      in.close();

    if (obj.m_file == "")
      return in;

    in.open(obj.m_file.c_str(), std::ios::in);

    if (in.fail() || in.bad()) {
      in.close();
      return in;
    }

    std::vector<key> tmp;
    typedef std::istream_iterator<key> string_input;
    copy(string_input(in), string_input(), back_inserter(tmp));
    typename std::vector<key>::iterator bvi = tmp.begin();
    typename std::vector<key>::iterator evi = tmp.end();
    while (bvi != evi) {
      obj.m_map[*(bvi)] = container();
      ++bvi;
    }

    in.close();
    return in;
  }  
  private:
    std::map<key, container> m_map;
    std::string m_file;
};

and inside the friend method " operator<< " 并在朋友方法“ operator<< ”中

You want to print the conents of the map and the generic container how would one go about doing this? 您要打印地图和通用container怎么办呢? How do you get an appropriate iterator to iterate through the contents of the generic container . 如何获得适当的迭代器来遍历通用container的内容。

I am trying it with: 我正在尝试:

container::iterator cbi;

CODE UPDATE 代码更新

With: 带有:

friend std::ostream& operator<< (std::ostream &out, file_to_map<key, container, container_type> &obj)
  {
    typedef typename std::map<key, container>::const_iterator mapItr;
    mapItr mbi = obj.m_map.begin();
    mapItr emi = obj.m_map.end();
    while (mbi != emi) {
      out << " -- " << mbi->first << " -- " << std::endl;
      typename container::const_iterator cbi = mbi->second.begin();
      typename container::const_iterator ebi = mbi->second.end();
      std::copy(cbi, mbi, std::ostream_iterator<container_type>(out, "\t\n"));
      ++mbi;
    }
    return out;
  }

I am getting the following compiler error: 我收到以下编译器错误:

g++ -o file_to_map -Wall ./file_to_map.h ./main.cpp ./code_finder.cpp \
        -L/usr/local/boost_1_48_0/stage/lib -lboost_filesystem -lboost_system -I /usr/local/boost_1_48_0/
In file included from ./code_finder.h:4,
                 from ./code_finder.cpp:1:
./file_to_map.h: In function ‘std::ostream& operator<<(std::ostream&, file_to_map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >&)’:
./code_finder.cpp:36:   instantiated from here
./file_to_map.h:62: error: no matching function for call to ‘copy(std::_Rb_tree_const_iterator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >&, operator<<(std::ostream&, file_to_map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >&)::mapItr&, std::ostream_iterator<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, char, std::char_traits<char> >)’

What am I missing? 我想念什么?

Use typename : 使用typename

typename container::iterator cbi;

Because iterator is a dependent name, as it depends on the type argument container of the class template. 因为iterator是一个从属名称,所以它取决于类模板的类型参数container Interestingly, if you've corrected used typename in other place, such as in operator<< : 有趣的是,如果您已在其他地方更正了使用的typename名,例如在operator<<

typedef typename std::map<key, container>::const_iterator mapItr;

Since you're working with const_iterator for the map which means the container objects which you would get using map's const iterator will be const objects, which in turn implies you need to use const_iterator for the containers as well, because they are the values of the map. 由于您正在为地图使用const_iterator ,这意味着您将使用地图的const迭代器获取的容器对象将是const对象,这又意味着您也需要对容器使用const_iterator ,因为它们是的值地图。 So I think you need to use this: 所以我认为您需要使用:

typename container::const_iterator cbi; //use this instead!

Reply to your edit: 回复您的编辑:

I see a typo here: 我在这里看到一个错字:

typename container::const_iterator cbi = mbi->second.begin();
typename container::const_iterator ebi = mbi->second.end();
std::copy(cbi, mbi, std::ostream_iterator<container_type>(out, "\t\n"));
            // ^^^ typo

The second argument to std::copy should be ebi , not mbi . std::copy的第二个参数应该是ebi ,而不是mbi That is why I usually name such variables as begin and end , instead of cbi and ebi . 这就是为什么我通常将这样的变量命名为beginend ,而不是cbiebi

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM