I have a class, let's call it ConstVector, that only defines cbegin/cend and not begin/end because I don't want to allow modifications to its members after construction. I tried to use the range based for loop like this:
ConstVector const_vector(1, 2, 3);
for(const auto &x : const_vector)
....
While the relevant part of the class looks like this:
template<class T>
class ConstVector
{
public:
ConstVector(std::initializer_list<T> values);
typename std::vector<T>::const_iterator cbegin(void) const;
typename std::vector<T>::const_iterator cend(void) const;
private:
std::vector<T> data;
};
template<class T>
ConstVector::ConstVector(std::initializer_list<T> values)
: data(values)
{
}
template<class T>
typename std::vector<T>::const_iterator ConstVector<T>::cbegin() const
{
return this->data.cbegin();
}
template<class T>
typename std::vector<T>::const_iterator ConstVector<T>::cend() const
{
return this->data.cend();
}
But my compiler complains:
‘begin’ was not declared in this scope
My question is: Do I have to implement begin/end? As far as I understood it, it should choose cbegin/cend if it's const auto &x
and not auto &x
. At least that's what would make sense to me. If I remove my range based for loop, everything compiles fine.
I also tried pretty much everything suggested here to make it const
, but that didn't help.
Do I have to implement begin/end?
Yes.
As far as I understood it, it should choose
cbegin/cend
if it'sconst auto &x
and notauto &x
.
That's not how the range-based for
is defined in the standard. Range-based for
always looks for begin()
and end()
. From https://timsong-cpp.github.io/cppwp/n3337/stmt.ranged.
otherwise, begin-expr and end-expr are
begin(__range)
andend(__range)
, respectively, wherebegin
andend
are looked up with argument-dependent lookup ([basic.lookup.argdep]). For the purposes of this name lookup, namespace std is an associated namespace.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With