Subject: [Boost-bugs] [Boost C++ Libraries] #4488: iterator_facade operator[] return type does not function correctly
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2010-07-29 15:06:17
#4488: iterator_facade operator[] return type does not function correctly
-------------------------------------------------------------------------------+
Reporter: justus.c79@⦠| Owner: dave
Type: Bugs | Status: new
Milestone: Boost 1.44.0 | Component: iterator
Version: Boost 1.44.0 | Severity: Problem
Keywords: iterator_facade, operator_brackets_proxy, operator[], operator [] |
-------------------------------------------------------------------------------+
iterator_facade::operator[] does not function correctly when
iterator_facade::reference is a reference to a class or structor and you
try to access member variables or functions via the returned reference. In
the following example program iterator_facade::reference is std::pair<int,
int>& and we try to access std::pair<int,int>::first via the
iterator_facade::operator[].
{{{
#!C++
#include <iostream>
#include <boost/iterator/iterator_facade.hpp>
template <typename T>
class IterTest : public boost::iterator_facade<IterTest<T>, T,
std::random_access_iterator_tag>
{
private:
// base class typedef
typedef boost::iterator_facade<IterTest<T>, T,
std::random_access_iterator_tag, T&> iterator_facade_;
public:
// Standard iterator typedefs
typedef typename iterator_facade_::value_type value_type;
typedef typename iterator_facade_::reference reference;
typedef typename iterator_facade_::pointer pointer;
typedef typename iterator_facade_::iterator_category iterator_category;
typedef typename iterator_facade_::difference_type difference_type;
// Constructors
IterTest() : p_(NULL) { }
explicit IterTest(T* p) : p_(p) { }
private:
// Core operations for iterator_facade
template <typename U>
bool equal(const IterTest<U>& other) const
{ return p_ == other.p_; }
void increment() { ++p_; }
void decrement() { --p_; }
reference dereference() const { return *p_; }
void advance(difference_type n) { p_ += n; }
template <typename U>
difference_type distance_to(const IterTest<U>& other) const
{ return (other.p_ - p_); }
// class friend
template <typename>
friend class IterTest;
friend class boost::iterator_core_access;
// iterator
T* p_;
};
int main() {
std::pair<int, int>* p = new std::pair<int, int>(1,2);
std::cout << p[0].first << std::endl; // Ok for pointers
std::vector<std::pair<int,int> > v(1, std::pair<int,int>(1,2));
std::vector<std::pair<int,int> >::iterator vit = v.begin();
std::cout << vit[0].first << std::endl; // Ok for std::vector::iterator
IterTest<std::pair<int, int> > it(p);
std::cout << it[0].first << std::endl; // error:
// 'class boost::detail::operator_brackets_proxy<IterTest<std::pair<int,
int> > >'
// has no member named 'first'
delete p;
return 0;
}
}}}
Note: Similar, code using pointer and std::vector::iterator works as
expected.
If we change:
{{{
#!C++
std::cout << it[0].first << std::endl;
}}}
to:
{{{
#!C++
std::cout << static_cast<std::pair<int,int>&>(it[0]).first << std::endl;
}}}
then the program works correctly. Obviously this is not a desireable
solution since we want the these iterators to work in the same way as
pointers and other standard library iterators.
I tested the above code with Apple GCC 4.0.1, Apple GCC 4.2.1, GCC 4.4.4,
GCC 4.5.0, Intel 11.1, and clang 1.1 release 27 compilers; all of them
give similar error messages.
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/4488> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:04 UTC