Using dynamic arrays like that becomes harder to maintain and doesn't really give you any benefits over using a std::vector
. You would need to store the size of each array separately.
Example:
#include <iterator>
#include <memory>
#include <utility>
template<typename T>
struct myarr {
myarr() = default;
myarr(size_t size) : arr(std::make_unique<T[]>(size)), m_size(size) {}
T& operator[](size_t idx) { return arr[idx]; }
const T& operator[](size_t idx) const { return arr[idx]; }
auto cbegin() const { return &arr[0]; }
auto cend() const { return std::next(cbegin(), m_size); }
auto begin() const { return cbegin(); }
auto end() const { return cend(); }
auto begin() { return &arr[0]; }
auto end() { return std::next(begin(), m_size); }
private:
std::unique_ptr<T[]> arr;
size_t m_size;
};
int main() {
myarr<myarr<std::string>> arr(4);
arr[0] = myarr<std::string>(5);
arr[1] = myarr<std::string>(3);
arr[2] = myarr<std::string>(4);
arr[3] = myarr<std::string>(2);
for(auto& inner : arr) {
for(const std::string& str : inner) {
// do stuff
}
}
}
The std::vector
-based code would only require the below and offers far more flexibility:
Example:
std::vector<std::vector<std::string>> arr(4);
arr[0].resize(5);
arr[1].resize(3);
arr[2].resize(4);
arr[3].resize(2);
std::string**
??