Question

I have the following function and vector:

template <class RandomIterator>  RandomIterator upperBound(RandomIterator start, RandomIterator end, const typename iterator_traits<RandomIterator>::reference t);

vector<int> v{1,2,3,3,4};

But it does not work when I call:

upperBound(v.begin(), v.end(), 1);

The error (from g++ and clang++) is some thing like "expecting lvalue; can not passing a rvalue to the 3 argument". However, shouldn't the following two types

const typename iterator_traits<RandomIterator>::reference
const typename iterator_traits<RandomIterator>::value_type&

equivalent to compilers?

By then way, when changing the function spec to

template <class RandomIterator>  RandomIterator upperBound(RandomIterator start, RandomIterator end, const typename iterator_traits<RandomIterator>::value_type& t);

everything works fine.

Was it helpful?

Solution

No, they aren't equivalent. When you have const some_typedef, the const applies to the outermost type of the typedef. So if some_typedef is a reference type (which in your case it is), then the const applies to the reference. Since there's no such thing as a const reference type, the const gets ignored.

That is, if the element type of your vector is int, then:

  • const typename iterator_traits<RandomIterator>::reference becomes int& const which is equivalent to just int&.
  • const typename iterator_traits<RandomIterator>::value_type& becomes const int&.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top