mercredi 3 août 2016

Range expression of range-based for loops to use const function overloads

When the range expression of a range-based for loop is a call to a member function with const and non-const overloads, it seems that the non-const overload is selected. As a result, the following program does not compile:

#include <iostream>
#include <vector>

class foo {
    public:
        const std::vector<int>& get_numbers() const { return numbers; }
    protected:
        std::vector<int>& get_numbers() { return numbers; }
    private:
        std::vector<int> numbers;
};

int main() {
    foo f;
    for (int x : f.get_numbers()) std::cout << x << std::endl;
}

Diagnostic message from gcc 5.3:

error: ‘std::vector<int>& foo::get_numbers()’ is protected

But a const version of get_numbers() is available and could be used. We can force it to be used by using a const reference to the foo instance, like this:

int main() {
    foo f;
    const foo& g = f;
    for (int x : g.get_numbers()) std::cout << x << std::endl;
}

Is there a better/easier way to tell the compiler that it can and should use the const member function overload, without explicitly making a const reference to the object?

There are some similar questions about making the range-based for loop use const iterators, but I haven't found any questions about making the loop's range expression const for the purposes of selecting function overloads.

Aucun commentaire:

Enregistrer un commentaire