Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

forcing use of cbegin()/cend() in range-based for

Tags:

c++

This question refers to:

When should I use the new ranged-for and can I combine it with the new cbegin/cend?

Based on that question, to force the use of cbegin() and cend(), one needs to do, for example:

for (auto& v: const_cast<decltype(container) const>(container)) 

That's a lot of boilerplate code for a construct that was supposed to eliminate it. Is there some more compact way to do it? The reason for my question is, that an implicitly shared container might take my use of begin() as a clue to detach itself.

like image 504
user1095108 Avatar asked Mar 20 '13 08:03

user1095108


People also ask

What is Cbegin and Cend in C++?

The set::cbegin() is a built-in function in C++ STL which returns a constant iterator pointing to the first element in the container. The iterator cannot be used to modify the elements in the set container. The iterators can be increased or decreased to traverse the set accordingly.

What is the difference between Cbegin and begin?

begin() returns an iterator to beginning while cbegin() returns a const_iterator to beginning. The basic difference between these two is iterator (i.e begin() ) lets you change the value of the object it is pointing to and const_iterator will not let you change the value of the object.

What does Cbegin return?

std::vector::cbegin Returns a const_iterator pointing to the first element in the container. A const_iterator is an iterator that points to const content.

Do range based for loops use iterators?

Range-Based 'for' loops have been included in the language since C++11. It automatically iterates (loops) over the iterable (container). This is very efficient when used with the standard library container (as will be used in this article) as there will be no wrong access to memory outside the scope of the iterable.


1 Answers

Update: std::as_const will be in C++17, in the <utility> header.

Prior to C++17, there's no built-in syntax for it; however, you can easily write a convenience wrapper:

template<typename T> constexpr const T &as_const(T &t) noexcept { return t; } for (auto &v: as_const(container)) 

Note that this calls begin() const rather than cbegin() specifically; the Standard container general requirements specify that cbegin() and begin() const behave identically.

If your container treats non-const iteration specially, it might make sense for it itself to have a member function:

const Container &crange() const noexcept { return *this; } for (auto &v: container.crange()) 
like image 87
ecatmur Avatar answered Sep 23 '22 07:09

ecatmur