在泛型类中获取泛型容器的迭代器:如何
getting an iterator to a generic container inside a generic class: HOW TO
这来自一个更大的上下文,但是我已经剥离了许多代码来简化问题。如果你觉得我遗漏了什么,请告诉我。
假设你有一个模板类定义为:
#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;
};
和友元方法" operator<<
"
你想打印地图的内容和通用的container
怎么做呢?如何获得一个合适的迭代器来遍历泛型container
.
我正在尝试:
container::iterator cbi;
代码更新
:
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, "tn"));
++mbi;
}
return out;
}
我得到以下编译错误:
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> >)’
我错过了什么?
使用typename
:
typename container::iterator cbi;
因为iterator
是一个依赖名称,因为它依赖于类模板的类型参数container
。有趣的是,如果你在其他地方使用了typename
,比如operator<<
:
typedef typename std::map<key, container>::const_iterator mapItr;
因为你正在使用const_iterator
的映射,这意味着容器对象,你会得到使用map的常量迭代器将是const
的对象,这反过来意味着你需要使用const_iterator
的容器,因为它们是映射的值。所以我认为你需要使用这个:
typename container::const_iterator cbi; //use this instead!
回复你的编辑:
我看到这里有个错别字:
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, "tn"));
// ^^^ typo
std::copy
的第二个参数应该是ebi
,而不是mbi
。这就是为什么我通常将这些变量命名为begin
和end
,而不是cbi
和ebi
。
相关文章:
- 使用迭代器时如何访问对象在向量中的位置?
- 如何在创建自定义迭代器时获得 std::p air 的第一个和第二个?
- 为什么以及如何C++更改旧迭代器的值
- 如何创建迭代器函数
- 使用一个 for 循环如何迭代和测试迭代器值?
- 如何为指向复杂值的迭代器专门化算法?
- C++ 如何为自己的迭代器类从迭代器转换为const_iterator?
- 如何实现常量迭代器?
- 如何为我的容器实现随机访问迭代器?
- 如何将迭代器调用转发给类的私有成员?
- C++如何乘以包含 std::variant 元素的向量的迭代器?正在执行迭代器类型的转换?
- 如何从目录迭代器中选择特定文件并进行比较
- 如何在目录迭代器中选择特定的目录条目
- 对于C++随机访问迭代器(矢量迭代器),迭代器之间的差异是如何计算的?
- 如何基于循环迭代器选择函数
- 当(例如)容器大小发生变化时,容器 end() 迭代器如何演变
- 迭代器如何在向量重新分配后更新
- 无效迭代器:如何在第一次使用时获取一些调试信息
- 在泛型类中获取泛型容器的迭代器:如何
- 迭代器如何映射/知道它们的当前位置或元素