Opened 11 years ago

Closed 11 years ago

#562 closed defect (fixed)

pair_second_iterator does not compile with const_iterator

Reported by: Peter Owned by: Peter
Priority: major Milestone: yat 0.6
Component: utility Version: 0.5.4
Keywords: Cc:

Description

The following code does not compile

typedef std::map<std::string, std::string> C;
C person2color;
person2color["me"] = "yellow";
person2color["you"] = "orange";
C::const_iterator begin = person2color.begin();
C::const_iterator end = person2color.begin();
std::set<std::string> words;
words.insert(utility::pair_second_iterator(begin), 
             utility::pair_second_iterator(end));

Change History (2)

comment:1 Changed 11 years ago by Peter

Milestone: yat 0.5.5yat 0.6
Status: newassigned

In the declaration:

template<class Iter>
boost::transform_iterator<
    PairSecond<typename std::iterator_traits<Iter>::value_type>, 
    Iter> 
pair_second_iterator(Iter i)

the problem is in the first template argument in the return type

PairSecond<typename std::iterator_traits<Iter>::value_type>, 

because value_type must never be const (according to the standard), implying that

iterator_traits<map<string, double>::const_iterator>::value_type

gives

pair<const string, double>

while we would like to get

const pair<const string, double>

because otherwise PairSecond will try to pass pair<const string, double>& which is not available from a const_iterator. We want to keep the const, and can accomplish this using a trick. iterator_traits<>::reference holds constness information so we can instead of

std::iterator_traits<Iter>::value_type

we can use

boost::remove_reference<typename iterator_traits<Iter>::reference>::type

which in our case will be

boost::remove_reference<const pair<const string, double>& >::type
const pair<const string, double>

This will change the signature of the function, but only when Iter is a const_iterator (i.e. *Iter returns a const reference). Note, however, that the function does not compile currently when Iter is a const_iterator, so the change will not break any existing code. Yet, my feeling is that we should move this change to 0.6 as it does change the return type, but thought are welcome.

BTW, the same problem obviously occur in pair_first_iterator too.

comment:2 Changed 11 years ago by Peter

Resolution: fixed
Status: assignedclosed

(In [2068]) fixes #562

Note: See TracTickets for help on using tickets.