3

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)?

1
  • You might take inspiration from Eigen (but they don't provide a way to have the syntax you're looking for either). Commented Nov 20, 2019 at 16:27

1 Answer 1

2

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"; } 

Live example.

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é.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.