How to get array size stored in unique_ptr?
No, there isn't. Dynamic arrays are a somewhat defective language feature. You'll essentially always want/need to pass the array length around separately (unless you have some kind of sentinel policy). So you might as well use std::vector
(if you don't mind the extra word for the capacity).
No, the information is lost.
If you need to keep track of it, use a vector instead or if you really do not wants the extra services, write a small wrapper around an allocated array. You can for example look at the std::dynarray
proposal that was kicked off the c++1y standard.
unique_ptr
does not carry the size information. You could use vector
, but there are two issues:
- The size is not fixed. That is sometimes an important property.
- Forces a value-initialization onto each element, even if you don't want to.
You can wrap unique_ptr
with a size and make a custom container:
#include <cstddef> // for size_t#include <cstdio> // for printf#include <memory> // for unique_ptr#include <utility> // for forwardtemplate <class T>struct DynArray final { private: std::unique_ptr<T[]> _data = nullptr; std::size_t _size = 0; public: static DynArray ofSize(std::size_t const size) { DynArray arr; arr._data.reset(size ? new T[size] : nullptr); arr._size = size; return arr; } template <class... Args> DynArray(Args&&... args) : _data(sizeof...(Args) ? new T[sizeof...(Args)]{std::forward<Args>(args)...} : nullptr), _size{sizeof...(Args)} {} DynArray(DynArray&& goner) noexcept : _data{std::move(goner._data)}, _size(goner._size) { goner._size = 0; } auto& operator=(DynArray&& goner) noexcept { if (this != &goner) { _data = std::move(goner._data); this->_size = goner._size; goner._size = 0; } return *this; } auto size() const noexcept { return _size; } auto const* begin() const noexcept { return _data.get(); } auto const* cbegin() const noexcept { return _data.get(); } auto* begin() noexcept { return _data.get(); } auto const* end() const noexcept { return begin() + _size; } auto const* cend() const noexcept { return begin() + _size; } auto* end() noexcept { return begin() + _size; } auto const* data() const noexcept { return begin(); } auto data() noexcept { return begin(); } auto const& operator[](std::size_t i) const noexcept { return _data[i]; } auto& operator[](std::size_t i) noexcept { return _data[i]; }};// Example usageint main() { auto arr = DynArray<int>{1, 2, 3, 4, 5}; for (auto elm : arr) printf("%d\n", elm); auto arr2 = DynArray<char>::ofSize(3); arr2[0] = 'A'; arr2[1] = 'B'; arr2[2] = 'C'; for (auto elm : arr2) printf("%c\n", elm);}