|
pstore2
|
A utility template intended to simplify the writing of the const- and non-const variants of member functions. More...
#include <type_traits>

Go to the source code of this file.
Classes | |
| struct | pstore::inherit_const< T, R, RC > |
Provides a member typedef inherit_const::type, which is defined as R const if T is a const type and R if T is non-const. More... | |
A utility template intended to simplify the writing of the const- and non-const variants of member functions.
It's not uncommon for a class to supply const- and non-const variants of the same member function where the constness of the return type changes according to the constness of the function itself. For example, std::vector<> has:
reference operator[] (size_type pos); const_reference operator[] (size_type pos) const;
Often the implementation of these two functions is identical: the constness is the only thing changing. This encourages us to want to share the implementation because duplicating code is almost always to be avoided. Writers typically adopt one of three solutions:
reference operator[] (size_type pos) {
return base_ + pos;
}
const_reference operator[] (size_type pos) const {
return base_ + pos;
}
reference operator[] (size_type pos) {
auto const * cthis = this;
return const_cast<reference> cthis->operator[] (pos);
}
const_reference operator[] (size_type pos) const {
return base_ + pos;
}
#define OPERATOR_INDEX(p) (base_ + (p))
reference operator[] (size_type pos) {
return OPERATOR_INDEX(pos);
}
const_reference operator[] (size_type pos) const {
return OPERATOR_INDEX(pos);
}
#undef OPERATOR_INDEX
The utility here is intended to resolve some of these concerns. For true one-liner member functions it is very likely overkill, but can be useful for implementations that are just fractionally more complex. In the example below I've added an assertion to the shared implementation.
class vector {
public:
...
reference operator[] (size_type pos) {
return index_impl (*this, pos);
}
const_reference operator[] (size_type pos) const {
return index_impl (*this, pos);
}
...
private:
template <typename Vector, typename ResultType = typename inherit_const<Vector,
reference>::type>
static ResultType index_impl (Vector & v, size_type pos) {
PSTORE_ASSERT (pos < v.size ());
return v.base_ + pos;
}
};
1.8.13