如何在使用模板的函数调用的花括号表达式中推导多维数组的大小

how to deduce the size of a multidimensional array in a curly brace expression of a function call with templates

我目前正在编写一个类型安全的启用编译时的张量 class,归结为

template<typename T, int... Sizes>
struct tensor {
  T elements[(Sizes * ...)];
  auto ptr() {return elements;}
  auto size() {return (Sizes * ...);}

  using value_type = T;
};

我想写一个方法,允许用数组作为表达式创建一个张量,就像这样:

make_tensor({1,2,3,4})make_tensor({{1,2},{3,4}}),给出一个向量和一个矩阵。我的 make_tensor 函数目前看起来像这样:

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

如果我先分配它,我可以用多维数组调用它,但是漂亮的语法不起作用:

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

根据我从这个 Failed to deduce bounds from initializer for multi-dimensional arrays 问题中收集到的信息,我的方法行不通。有没有其他可能的推导方式(例如使用初始化列表)?

您不能从嵌套 {{}}.

中推导出多维数组边界

你可以通过添加一些标记来推断它。

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.

array 推导指南将后面的 {} 表达式拆开并推导出 array 模板的类型。

所以:

make_tensor(a{a{1,2},a{3,4}})

是可以的,甚至

tensor{ tensor{1,2}, tensor{1,2} }

因为make函数有点过时了。