For some reasons I have to implement a multidimensional array class in C++. The array in question is something like this:
template <typename T, typename = std::enable_if_t<std::is_arithmetic_v<T>>>
class Array final
{
private:
std::vector<size_t> shape_;
std::vector<T> data_;
public:
// Some public methods
}
T
is the type of elements stored in the array, and that the dimensions of the array is not templated since the user should be able to reshape the array, for example:
Array<int> array = Array<int>::zeros(3, 2, 4);
array.reshape(4, 6);
Though implementation of the functions mentioned above went quite smoothly, I stuck at the "beginning" of implementing this class, that is to initialize the array... My questions are as follows:
Is there any method to have an constructor like this, such that nested initializer lists of different depths create different arrays, like:
Array<int> a = {1, 2}; // Dimension: 1, Shape: 2 Array<int> b = {{1}, {2}}; // Dimension: 2, Shape: 2x1
My approach to implement the constructors made these two arrays the same, which is not what I want. Plus, clang complained about the braced scalars, which seem to be the problem. Currently my naive approach which suffers from the problem above looks like this
... Array() :data_(0), shape_{0} {} Array(std::initializer_list<T> list) :data_(list), shape_{list.size()} {} Array(std::initializer_list<Array> lists) { // Implementation } ...
It's easy for the compiler to deduct the types for the following arrays:
Array c = {1, 2}; // T = int Array d = {1.0, 2.0}; // T = double
But I failed to write a working deduction guide for multidimensional ones:
Array e = {{1, 2}, {3, 4}}; // Expects T = int Array f = {{1.0, 2.0}, {3.0, 4.0}}; // Expects T = double
Is there any way to write a type deduction guide for this class?