I'm currently writing a typesafe compiletime-enabled tensor class, which boils down to
template<typename T, int... Sizes>
struct tensor {
T elements[(Sizes * ...)];
auto ptr() {return elements;}
auto size() {return (Sizes * ...);}
using value_type = T;
};
I wanted to write a method that allows to create a tensor with arrays as an expression, like that:
make_tensor({1,2,3,4})
or make_tensor({{1,2},{3,4}})
, giving a vector and a matrix. my make_tensor
function currently looks like this:
template<template<typename, int...> class Fill, typename Type, int... Sizes>
struct array_to_index {
using type = Fill<Type, Sizes...>;
};
template<template<typename, int...> class Fill, typename Type, int Size, int... Sizes>
struct array_to_index<Fill, Type[Size], Sizes...> {
using type = typename array_to_index<Fill, Type, Sizes..., Size>::type;
};
template<template<typename, int...> class Fill, typename Type>
using array_to_index_t = typename array_to_index<Fill, Type>::type;
template<typename Type, int Size>
auto make_tensor(const Type (&arr)[Size]) {
using tensor_t = array_to_index_t<tensor, Type[Size]>;
tensor_t tensor;
using ptr_t = const typename tensor_t::value_type *;
for(int i = 0; i < tensor.size(); ++i)
tensor.elements[i] = reinterpret_cast<ptr_t>(arr)[i];
return tensor;
}
I can call this with a multidimensional array if I assign it first, but the nice syntax doesn't work:
int main() {
//auto matrix = make_tensor({{0,1},{2,3},{4,5}}); // doesn't work
int arr[][2] = {{0,1},{2,3},{4,5}};
auto other = make_tensor(arr); // works
assert(other.elements[3] == 3);
}
With what I gather from this Failed to deduce bounds from initializer for multi-dimensional arrays question, my approach won't work. Is there any other way this deduction is possible (e.g with initializer lists)?
You cannot deduce multi dimensional array bounds from nested {{}}
.
You could deduce it by adding some tokens.
using namespace std;
auto arr = array{ array{1,2}, array{3,4} };
for (auto row : arr) {
for (auto e : row) {
std::cout << e << ",";
}
std::cout << "\n";
}
The array
deduction guide tears apart the {}
expression following and deduces the type of the array
template.
So:
make_tensor(a{a{1,2},a{3,4}})
is possible, or even
tensor{ tensor{1,2}, tensor{1,2} }
as make
functions are a bit passé.