In the following code, when calling arr.begin()
on a const Array<10>
object, it fails to find the const function Accessor::begin() const
, and instead only tries MutableAccessor::begin()
and fails because arr
is const.
When using arr.cbegin()
, it works correctly.
Also when both the const and non-const overload of a function are defined in the same class, it works correctly.
I see that inside the definition of Array
and MutableAccessor
, begin()
would be a dependent name on the template arguments, but what is the reason why when called from outside, MutableAccessor::begin()
seems to have priority?
#include <array>
#include <iostream>
template<std::size_t Size, class Derived>
struct Accessor {
const int* begin() const { return this_()->array.data(); }
const int* cbegin() const { return this_()->array.data(); }
const Derived* this_() const { return static_cast<const Derived*>(this); }
};
template<std::size_t Size, class Derived>
struct MutableAccessor : Accessor<Size, Derived> {
int* begin() { return this_()->array.data(); }
Derived* this_() { return static_cast<Derived*>(this); }
};
template<std::size_t Size>
struct Array : MutableAccessor<Size, Array<Size>> {
std::array<int, Size> array;
};
void f(const Array<10>& arr) {
std::cout << *arr.begin() << std::endl; // fails to find Accessor::begin()
}
int main() {
Array<10> arr;
f(arr);
}
You need to sign in to view this answers