[英]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
. 这就是为什么我通常将这样的变量命名为begin
和end
,而不是cbi
和ebi
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.