Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is cbegin/cend not enough for a range based for loop?

Tags:

c++

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.

like image 493
Shadowigor Avatar asked Jun 02 '17 15:06

Shadowigor


1 Answers

Do I have to implement begin/end?

Yes.

As far as I understood it, it should choose cbegin/cend if it's const auto &x and not auto &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) and end(__range), respectively, where begin and end are looked up with argument-dependent lookup ([basic.lookup.argdep]). For the purposes of this name lookup, namespace std is an associated namespace.

like image 185
R Sahu Avatar answered Oct 19 '22 14:10

R Sahu