Is there a way to have two getters with different accesses and use in for loop one of them?

Viewed 54
class Foo {
    // friend Bar;

    public: const std::list<int*>& numbs () const { // (1)
        return mNumbs;
    }

    protected: std::list<int*>& numbs () { // (2)
        return mNumbs;
    }

    private: std::list<int*> mNumbs;
};

int main () {
    Foo foo;
    for (const auto& e : foo.numbs()) { // (3)
        // some work...
    }
}

My intention is to force to use (1) method for clients and (2) method for friends of Foo class. However compiler is trying to use (2) method that is protected in for statement and error is occured (3):

std::__cxx11::list<int*>& Foo::numbs()’ is protected within this context

I found some solutions:

  1. Changing name of (2) method (to numbs_ for example).
  2. Changing access class of (2) method to public (I'm not satisfied with that).

Does anyone know any better idea?

1 Answers

Method 1 is not a better match since foo is not a constant object. It will only be called if your object is constant.

If your callers choose to mark the object as a const, only then the error will go away. For instance, this will work as expected:

const Foo foo;
for (const auto& e : foo.numbs()) { // (3)
    // some work...
}

Seems like a bad idea to design it like this imo.

On a side note, you also need to know that visibility and accessibility in C++ are different things. Both methods are visible, but only one is accessible. And the one which is a better match is not accessible outside the type or derived types. Hence the error.

P.S.: As noted in the comments, a const_cast<> will also achieve the same effect.

Related