Errer passing an interator to a function

What am I missing about passing an iterator to a function?

I'm getting this error:

message : A non-const reference may only be bound to an lvalue
message : see declaration of 'display_numbers'

Is numbers.rbegin() the non-lvalue that can't be bound?

I changed the function to pass const & to see what would happen:

template<typename T> std::ostream& display_numbers(const T& begin, const T& end)

then I got this error:

error C2678: binary '++': no operator found which takes a left-hand operand of type 'const T' (or there is no acceptable conversion)

Which seems to make sense. You can't iterate something that's constant.

So how do I fix this code so it will run correctly?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <deque>

template<typename T> std::ostream& display_numbers(T& begin, T& end)
{
    for (; begin != end; ++begin)
    	std::cout << *begin << " ";
    return std::cout;
}

int main()
{
    int array[] = { 4, 6, 8 };
    std::deque<int> numbers(array, array + 3);
    display_numbers(numbers.rbegin(), numbers.rend()) << std::endl;
    return 0;
}
.
Last edited on
> So how do I fix this code so it will run correctly?

Pass iterators by value.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <deque>

template < typename ITERATOR >
std::ostream& display_numbers( ITERATOR begin, ITERATOR end, std::ostream& stm = std::cout )
{
    for ( ; begin != end; ++begin ) stm << *begin << " ";
    return stm ;
}

int main()
{
    const int array[] = { 4, 6, 8 };
    std::deque<int> numbers(array, array + 3);
    display_numbers( numbers.rbegin(), numbers.rend() ) << '\n' ;
}

http://coliru.stacked-crooked.com/a/9fc356a626eb6527
Thank you!
C++20 (range adapter):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <deque>
#include <ranges>

template < typename RANGE >
std::ostream& display_numbers( const RANGE& range, std::ostream& stm = std::cout )
{
    for ( auto&& item : range ) stm << item << ' ' ;
    return stm ;
}

int main()
{
    const int array[] = { 2, 3, 4, 5, 6, 7, 8  } ;
    const std::deque<int> numbers( array, array + std::size(array) );
    
    // https://en.cppreference.com/w/cpp/ranges/reverse_view
    const std::ranges::reverse_view reverse_view_deque{numbers} ;
    display_numbers(reverse_view_deque) << '\n' ;
    
    const std::ranges::reverse_view reverse_view_array{array} ;
    display_numbers(reverse_view_array) << '\n' ;
    
    for( auto&& v : numbers | std::views::reverse ) std::cout << v << ' ' ;
    std::cout << '\n' ;
}

http://coliru.stacked-crooked.com/a/9710645c25fadd84
I have some example code that runs with iterators passed by reference. Is there a time to use references and a time not to?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <deque>

template < class T > void
display_numbers(const T& begin, const T& end)
{
	T iter;
	for (iter = begin; iter != end; ++iter)
	{
		std::cout << *iter << " ";
	}
	std::cout << std::endl;
}

int
main()
{
	int array[] = { 1, 2, 3 };
	std::deque <int> numbers(array, array + 3);
	display_numbers(numbers.begin(), numbers.end());
	return 0;
}
Last edited on

What does this mean:
message : A non-const reference may only be bound to an lvalue
> I have some example code that runs with iterators passed by reference.
> Is there a time to use references and a time not to?

In general, iterators are expected to be cheaply copyable types.
The general thumb rule is: pass an iterator by reference to non-const if the iterator should be modified by the function (eg. std::advance); otherwise pass iterators by value.


> What does this mean:
> message : A non-const reference may only be bound to an lvalue

Exactly what it says:
1
2
int& r1 = 23 ; // *** error *** : non-const reference may only be bound to an lvalue
const int& r2 = 23 ; // fine; reference to const (lifetime of the temporary is extended) 
Thanks, I understand.
Topic archived. No new replies allowed.