如何在使用模板的函数调用的花括号表达式中推导多维数组的大小
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";
}
array
推导指南将后面的 {}
表达式拆开并推导出 array
模板的类型。
所以:
make_tensor(a{a{1,2},a{3,4}})
是可以的,甚至
tensor{ tensor{1,2}, tensor{1,2} }
因为make
函数有点过时了。
我目前正在编写一个类型安全的启用编译时的张量 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";
}
array
推导指南将后面的 {}
表达式拆开并推导出 array
模板的类型。
所以:
make_tensor(a{a{1,2},a{3,4}})
是可以的,甚至
tensor{ tensor{1,2}, tensor{1,2} }
因为make
函数有点过时了。