gpt4 book ai didi

c++ - 如何制作接受任何等级数组的函数或构造函数

转载 作者:行者123 更新时间:2023-12-03 06:50:16 25 4
gpt4 key购买 nike

我有一个围绕 vector 和形状的包装结构,如下所示:

template <std::size_t N>
struct array_type {
std::array<std::size_t, N> shape;
std::vector<float> data;
};
我希望能够构建一个 array_type来自任何数组 float[N] , float[N][M] , 等等。
目前,我对每个等级都有一个函数,例如
template <std::size_t N>
array_type<1> _1d(const deel::formal::float_type (&values)[N]) {
return {{N},
std::vector<float_type>(
reinterpret_cast<const float_type*>(values),
reinterpret_cast<const float_type*>(values) + N)};
}

template <std::size_t N>
array_type<2> _2d(const deel::formal::float_type (&values)[N][M]) {
return {{N, M},
std::vector<float_type>(
reinterpret_cast<const float_type*>(values),
reinterpret_cast<const float_type*>(values) + N * M)};
}
我想写一些类似的东西:
template <class Array>
array_type<std::rank_v<Array>> make_array(Array const&);
...但这不适用于初始化列表:
auto arr1 = _1d({1, 2, 3}); // Ok
auto arr2 = make_array({1, 2, 3}); // Ko
有没有办法让这个 make_array ?或者(因为我认为这是不可能的),至少有类似 make_array<1>({1, 2, 3}) 的东西排名在哪里明确指定?

最佳答案

array_type::shape可以用 std::extent 生成使用一些模板元编程:

template<typename Array, std::size_t... I>
auto extents_impl(const Array& a, std::index_sequence<I...>)
{
return std::array{std::extent_v<Array, I>...};
}

template<typename Array>
auto extents(const Array& a)
{
return extents_impl(a, std::make_index_sequence<std::rank_v<Array>>());
}
有了这个, make_array可以写成:
template <class Array, std::enable_if_t<std::is_same_v<std::remove_cv_t<std::remove_all_extents_t<Array>>, float>, int> = 0> // magic incantation :)
array_type<std::rank_v<Array>> make_array(Array const& a)
{
array_type<std::rank_v<Array>> ret {
.shape = extents(a),
.data = std::vector<float>(sizeof a / sizeof(float)),
};
std::memcpy(ret.data.data(), &a, sizeof a);
return ret;
}
我用 memcpy根据标准的严格解释,避免潜在的指针类型别名违规和在子数组边界之外进行迭代的技术性是 UB。

...but that does not work for initializer list:


添加一个重载:
template <std::size_t N>
array_type<1> make_array(float const (&a)[N])
{
return make_array<float[N]>(a);
}
或者,您可以在调用中指定数组类型:
make_array<float[2][3]>({{1, 2, 3},{4, 5, 6}});
这不需要过载。

关于c++ - 如何制作接受任何等级数组的函数或构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64645275/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com