boost::迭代器_facade操作符->;()未能编译
考虑以下代码:boost::迭代器_facade操作符->;()未能编译,boost,iterator-facade,Boost,Iterator Facade,考虑以下代码: #include <boost/iterator/iterator_facade.hpp> #include <map> // Class implements an stl compliant iterator to access the "sections" stored within a configuration. template < typename _Iterator, typename _Reference >
#include <boost/iterator/iterator_facade.hpp>
#include <map>
// Class implements an stl compliant iterator to access the "sections" stored within a configuration.
template < typename _Iterator, typename _Reference >
class Section
: public boost::iterator_facade<
Section< _Iterator, _Reference >,
_Iterator,
boost::random_access_traversal_tag,
_Reference
>
{
private:
// Define the type of the base class:
typedef boost::iterator_facade<
Section< _Iterator, _Reference >,
_Iterator,
boost::random_access_traversal_tag,
_Reference
> base_type;
public:
// The following type definitions are common public typedefs:
typedef Section< _Iterator, _Reference > this_type;
typedef typename base_type::difference_type difference_type;
typedef typename base_type::reference reference;
typedef _Iterator iterator_type;
public:
explicit Section( const iterator_type it )
: m_it( it )
{ }
// Copy constructor required to construct a const_iterator from an iterator:
template < typename _U >
Section( const Section< _U, _Reference > it )
: m_it( it.m_it )
{ }
private:
// The following classes are friend of this class to ensure access onto the private member:
friend class boost::iterator_core_access;
template < typename _Iterator, typename _Reference > friend class Section;
void increment( ){ ++m_it; } // Advance by one position.
void decrement( ){ --m_it; } // Retreat by one position.
void advance( const difference_type& n ){ m_it += n }; // Advance by n positions.
bool equal( const this_type& rhs ) const{ return m_it == rhs.m_it; } // Compare for equality with rhs.
reference dereference( ) const { return m_it->second; } // Access the value referred to.
difference_type distance_to( const this_type& rhs ) const{ return rhs.m_it - m_it; } // Measure the distance to rhs.
private:
// Current "section" iterator:
iterator_type m_it;
};
struct Data
{
void f( ) const
{ }
};
typedef std::map< int, Data > map_type;
typedef Section< const map_type::const_iterator, const Data& > iterator_type;
map_type g_map;
iterator_type begin( )
{
return iterator_type( g_map.begin( ) );
}
void main( )
{
iterator_type i = begin( );
// i->f( ); // <--- error C2039: 'f' : is not a member of 'std::_Tree_const_iterator<_Mytree>'
( *i ).f( );
}
#包括
#包括
//类实现符合stl的迭代器,以访问存储在配置中的“节”。
模板
班级
:public boost::迭代器<
章节<\u迭代器,\u参考>,
_迭代器,
boost::随机访问遍历标记,
_参考文献
>
{
私人:
//定义基类的类型:
typedef boost::迭代器<
章节<\u迭代器,\u参考>,
_迭代器,
boost::随机访问遍历标记,
_参考文献
>基型;
公众:
//以下类型定义是常见的公共类型定义:
typedef节<\u迭代器,\u引用>此类型;
typedef typename base_type::difference_type difference_type;
typedef typename base_type::reference引用;
类型定义迭代器迭代器类型;
公众:
显式部分(常量迭代器\键入它)
:m_it(it)
{ }
//从迭代器构造常量迭代器所需的复制构造函数:
模板
章节(施工章节<\U,\U参考>it)
:m_it(it.m_it)
{ }
私人:
//以下类是此类的朋友,以确保访问私有成员:
朋友类boost::迭代器\u核心\u访问;
模板朋友类部分;
void increment(){++m_it;}//前进一个位置。
无效减量(){--m_it;}//后退一个位置。
void advance(const difference_type&n){m_it+=n};//按n个位置前进。
bool equal(const this_type&rhs)const{return m_it==rhs.m_it;}//比较是否与rhs相等。
reference dereference()const{return m_it->second;}//访问引用的值。
差分类型距离到(const this类型&rhs)const{return rhs.m_it-m_it;}//测量到rhs的距离。
私人:
//当前“节”迭代器:
迭代器类型m_it;
};
结构数据
{
空f()常数
{ }
};
typedef std::mapmap\u type;
typedef节<常量映射类型::常量迭代器,常量数据&>迭代器类型;
地图类型g地图;
迭代器类型begin()
{
返回迭代器类型(g_map.begin());
}
空干管()
{
迭代器类型i=begin();
//调用了i->f();//()。所以我有点困惑,因为操作符->()试图返回std::map::迭代器。有什么想法吗?迭代器在取消引用时返回迭代器。要获得f
部分,需要取消引用两次
看起来很像您误解了模板参数对iterator\u facade
的含义。第二个参数是不应该是任何迭代器类型(这就是造成所有问题的原因)。相反,您应该使用它来命名值\u类型
从您指定dereference
操作(和Ref
)并希望在main(i->f()
)中使用它的方式来看,您似乎只想迭代映射的值。因此,我还使用了更具描述性的名称重写了整个过程,结果如下:
#include <boost/iterator/iterator_facade.hpp>
#include <map>
// Class implements an stl compliant iterator to access the "sections" stored within a configuration.
template <typename Map, typename Value = typename Map::mapped_type>
class MapValueIterator : public boost::iterator_facade<MapValueIterator<Map>, Value, boost::random_access_traversal_tag, Value const&> {
private:
// Define the type of the base class:
typedef Value const& Ref;
typedef boost::iterator_facade<MapValueIterator<Map>, Value, boost::random_access_traversal_tag, Ref> base_type;
public:
// The following type definitions are common public typedefs:
typedef MapValueIterator<Map> this_type;
typedef typename base_type::difference_type difference_type;
typedef typename base_type::reference reference;
typedef typename Map::const_iterator iterator_type;
public:
explicit MapValueIterator(const iterator_type it) : m_it(it) {}
// Copy constructor required to construct a const_iterator from an iterator:
template <typename U, typename V> MapValueIterator(const MapValueIterator<U,V> it) : m_it(it.m_it) {}
private:
// The following classes are friend of this class to ensure access onto the private member:
friend class boost::iterator_core_access;
template <typename U, typename V> friend class MapValueIterator;
void increment() { std::advance(m_it); } // Advance by one position.
void decrement() { std::advance(m_it, -1); } // Retreat by one position.
void advance(const difference_type &n) { std::advance(m_it, n); } // Advance by n positions.
bool equal(const this_type &rhs) const { return m_it == rhs.m_it; } // Compare for equality with rhs.
reference dereference() const { return m_it->second; } // Access the value referred to.
difference_type distance_to(const this_type &rhs) const { return rhs.m_it - m_it; } // Measure the distance to rhs.
private:
// Current iterator:
iterator_type m_it;
};
#include <iostream>
struct Data {
void f() const {
std::cout << __PRETTY_FUNCTION__ << "\n";
}
};
typedef std::map<int, Data> map_type;
template <typename Map>
MapValueIterator<Map> map_value_iterator(Map const& m) {
return MapValueIterator<Map>(m.begin());
}
int main() {
map_type g_map;
auto i = map_value_iterator(g_map);
i->f();
}
如你所料
注意,在很多地方,我使用标准库工具实现了成员函数。另外,请注意,迭代器“模拟”了随机访问,但它没有预期的性能特征(增量为O(n))
最后一点注意:我建议不要使用隐式转换构造函数。我想你可以不用它
CharStyle引用类型通常应相同(但ref限定),除非在少数情况下您实际“代理”值。这是一个高级主题,很少使用。再次是一个很好的答案。非常感谢。是的,如何使用value参数是一个误解。现在它按预期工作!
void Data::f() const