Boost logo

Boost Users :

From: David Abrahams (dave_at_[hidden])
Date: 2004-07-01 09:24:20


Angus Leeming <angus.leeming_at_[hidden]> writes:

> Consider a container such as
> std::vector<std::pair<int, std::string> > my_container;
>
> I want to be able to iterate over the ints of this container so, following
> the tutorial to the iterator_adaptor docs, came up with
>
> template <typename BaseIterator>
> class first_iter
> : public boost::iterator_adaptor<
> first_iter<BaseIterator>,
> BaseIterator,
> boost::use_default,
> boost::use_default,
> typename BaseIterator::value_type::first_type &
> >
> {
> // snip body
> };

Why struggle?

boost::transform_iterator should give you just what you need:

   struct select1st
   {
       template <class P>
       P::first_type& operator()(P& pair) { return pair.first; }
       template <class P>
       P::first_type const& operator()(P const& pair) { return pair.first; }
   };

   namespace boost
   {
      template <class T>
      struct result_of<select1st(T&)>
      {
          typedef P::first_type& type;
      };
      template <class T>
      struct result_of<select1st(T const&)>
      {
          typedef P::first_type const& type;
      };
   }

   transform_iterator<select1st, iter>

> This works fine so long as BaseIterator::value_type is not const, but falls
> over when it is because I've defined the 'super_t::reference' type to be
> mutable.
>
> I guess that I need a piece of metafunction magic, but my naive
> implementation fails
>
> typename boost::mpl::apply_if<
> boost::is_const<typename BaseIterator::value_type>
> , typename BaseIterator::value_type::first_type const &
> , typename BaseIterator::value_type::first_type &
> >::type

Try plain mpl::if_. apply_if invokes one of two nullary
metafunctions, but a (const) int& is not a metafunction.

> trial.C:38: error: no type named `type' in `struct
> boost::mpl::apply_if<
> boost::is_const<std::pair<int, std::string> >,
> const int&,
> int&>'
>
> I must admit I'm a bit baffled. There plainly is a 'type' in the apply_if
> class template.

Nope:

  template <class C, class T, class F>
  struct apply_if : typename if<C,T,F>::type
  {};

> Any pointers? I attach the code as I have it.

> While I'm at it, is there not something in the MPL that will return
> the appropriate const-qualified reference for me?

What do you mean?

> None of the header file names in boost/mpl jump out and grab me, but
> I may well be looking in the wrong place.

-- 
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net