(also see Is there a good way not to hand-write all twelve required Container functions for a custom type in C++? )
For a class such as
namespace JDanielSmith {
class C
{
const size_t _size;
const std::unique_ptr<int[]> _data;
public:
C(size_t size) : _size(size), _data(new int[size]) {}
inline const int* get() const noexcept { return _data.get(); }
inline int* get() noexcept { return _data.get(); }
size_t size() const noexcept { return _size; }
};
}
what is the preferred way to expose iteration? Should I write begin()
/end()
(and cbegin()
/cend()
) member functions?
const int* cbegin() const {
return get();
}
const int* cend() const {
return cbegin() + size();
}
or should these be non-member functions?
const int* cbegin(const C& c) {
return c.get();
}
const int* cend(const C& c) {
return cbegin(c) + c.size();
}
Should begin()
/end()
have both const
and non-const
overloads?
const int* begin() const {
return get();
}
int* begin() {
return get();
}
Are there any other things to consider? Are there tools/techniques to make this "easy to get right" and reduce the amount of boiler-plate code?
Some related questions/discussion include: