Re: [Boost-users] iterator_facade Boost 1.57
On Tue, 04 Nov 2014 14:07:09 +0000 (UTC) gast128 wrote:
Dear all,
Just trying out 1.57, since we are already 5 releases behind due to all kinds of compilation errors with Boost and our software. Below simplified code doesn't compile on vs2010:
template <typename DerivedType> struct IteratorFacade : public boost::iterator_facade<DerivedType, int, std::random_access_iterator_tag> { typedef boost::iterator_facade<DerivedType, int, std::random_access_iterator_tag> base;
IteratorFacade (); virtual ~IteratorFacade ();
friend class boost::iterator_core_access;
reference dereference () const; };
struct MyIteratorFacade : IteratorFacade<MyIteratorFacade> { };
What do I wrong?
Hi, I'm gcc 4.9.1 on Ubuntu 14.04. The reason this doesn't compile is that the "reference" typedef is contained in the glue class boost::iterator_facade, which is a base class of IteratorFacade<MyIteratorFacade>. When you write "reference" inside the later, the name is not being looked up in the base class. So you should write: typename base::reference dereference() const; If you want to use "reference" in many places in IteratorFacade<>, pull the typedef from its base with: typedef typename base::reference reference; or, if using C++11: using typename base::reference; Note: whether you pull it up or not, you can always get the typedef as IteratorFacade<...>::reference, or MyIteratorFacade::reference in your case. (See the example below, where I'm not pulling it up, but I can still find it.) I would also add the observation that your construct creates an unusual derivation. Usually, the iterator class you want to define has boost::iterator_facade as its direct base. In your case, boost::iterator_facade is the base of the base of your iterator class (so, 2 levels down): MyIteratorFacade : IteratorFacade<MyIteratorFacade> : boost::iterator_facade<MyIteratorFacade, ...> I'm not sure this would cause any problems, just be on the lookout for missing constructors. For example, this compiles just fine for me: #include <type_traits> #include <boost/iterator/iterator_facade.hpp> struct MyIteratorFacade : public boost::iterator_facade<MyIteratorFacade, int, std::random_access_iterator_tag> { typedef boost::iterator_facade<MyIteratorFacade, int, std::random_access_iterator_tag> base; MyIteratorFacade (); virtual ~MyIteratorFacade (); friend class boost::iterator_core_access; typename base::reference dereference() const; }; static_assert(std::is_same< MyIteratorFacade::value_type, int >::value, "MyIteratorFacade::value_type != int"); static_assert(std::is_same< MyIteratorFacade::reference, int& >::value, "MyIteratorFacade::reference != int&"); static_assert(std::is_same< MyIteratorFacade::pointer, int* >::value, "MyIteratorFacade::pointer != int*"); static_assert(std::is_same< std::iterator_traits<MyIteratorFacade>::value_type, int >::value, "iterator_traits<MyIteratorFacade>::value_type != int"); static_assert(std::is_same< std::iterator_traits<MyIteratorFacade>::reference, int& >::value, "iterator_traits<MyIteratorFacade>::reference != int&"); static_assert(std::is_same< std::iterator_traits<MyIteratorFacade>::pointer, int* >::value, "iterator_traits<MyIteratorFacade>::pointer != int*"); I compile with: g++ -Wall -Wextra -pedantic -std=c++11 -I${BOOST_INCLUDE_1_57} -c (I'm only using c++11 for static_assert.) M
participants (1)
-
Matei David