У меня есть следующая функция и вектор:
template <class RandomIterator> RandomIterator upperBound(RandomIterator start, RandomIterator end, const typename iterator_traits<RandomIterator>::reference t);
vector<int> v{1,2,3,3,4};
Но это не работает, когда я звоню:
upperBound(v.begin(), v.end(), 1);
Ошибка (из g ++ и clang ++) — это что-то вроде «ожидание lvalue; невозможно передать значение r в аргумент 3». Тем не менее, не должны следующие два типа
const typename iterator_traits<RandomIterator>::reference
const typename iterator_traits<RandomIterator>::value_type&
эквивалентно компиляторам?
Кстати, при изменении спецификации функции на
template <class RandomIterator> RandomIterator upperBound(RandomIterator start, RandomIterator end, const typename iterator_traits<RandomIterator>::value_type& t);
все отлично работает
Нет, они не эквивалентны. Когда у тебя есть const some_typedef
, const
применяется к внешнему типу typedef. Так что если some_typedef
является ссылочным типом (который в вашем случае это), то const
относится к ссылке. Так как нет такой вещи как const
ссылочный тип, const
игнорируется
То есть, если тип элемента вашего вектора int
, затем:
const typename iterator_traits<RandomIterator>::reference
становится int& const
что эквивалентно просто int&
,const typename iterator_traits<RandomIterator>::value_type&
становится const int&
,Других решений пока нет …