英文:
how do we add up arrarys of the same length at compile time
问题
专家们!我正在考虑如何使用模板编程在编译时使用C++17或C++20完成逐元素数组加法。例如,3个数组 {1,2,3}, {2,4,6}, {3,6,9} 将被相加得到 { 6, 12, 18 }。给定数组中相同索引的所有元素将被相加。以下是我的初始思路。
template <int... I>
struct Seq {};
template <template<int...> typename... Seqs>
struct addSeq{};
int main(){
static_assert(std::is_same_v<addSeq<Seq<1, 2, 3>, Seq<2, 4, 6>, Seq<3, 6, 9>>::type, Seq<6, 12, 18>>);
}
有没有专家能提供一些见解?
我遇到的第一个问题是,如果我为结构体 addSeq 使用这样的模板接口:
template <template<int...> typename... Seqs>
那么我将不得不为每个 Seqs 中的每个 int..T 传递参数给 addSeq{}。我不知道如何设计结构体 addSeq,以便我只能像这样使用它:
addSeq<Seq<1, 2, 3>, Seq<2, 4, 6>, Seq<3, 6, 9>>::type
英文:
experts! I am thinking how to use template programing to finish element-wise array addition at compile time using C++17 or C++20. For example, 3 arrs {1,2,3}, {,2,4,6}, {3,6,9} would be added up to { 6, 12, 18 }. All elements at the same index on the given arrays would be added up. The following is my initial thougt.
template <int... I>
struct Seq {};
template < template<int...> typename...Seqs >
struct addSeq{};
int main(){
static_assert(std::is_same_v<addSeq<Seq<1, 2, 3>,Seq<2, 4, 6>, Seq<3, 6, 9> >::type, Seq<6, 12, 18>>);
}
Any expert could provide some insigh?
the first problem I am running into is if I use such template interface for struct addSeq{}:
template < template<int...> typename...Seqs >
then I would have pass every int..T for every Seqs to addSeq{}. I have no clue how to desgin struct addSeq such that I can only use it like
addSeq<Seq<1, 2, 3>,Seq<2, 4, 6>, Seq<3, 6, 9> >::type
答案1
得分: 2
你仍然可以在编译时使用 std::array,因为它是constexpr友好的(也适用于C++17)。因此,在编译时处理数组的基本构建块仍然是 std::array。所以我认为没有必要通过模板参数来处理值的额外复杂性,然后解决方案看起来像这样:
#include <array>
template<typename type_t, std::size_t N, std::size_t M>
static constexpr auto sum_arrays(const std::array<std::array<type_t, M>, N>& arrays)
{
std::array<type_t, M> sum{};
for (const auto& array : arrays)
{
for (std::size_t index{}; index < M; ++index)
{
sum[index] += array[index];
}
}
return sum;
}
int main()
{
static constexpr std::array<std::array<int, 3>, 4> arrays
{{
{1,2,3},
{4,5,6},
{7,8,9},
{10,11,12}
}};
static constexpr auto sum = sum_arrays(arrays);
static_assert(sum[0] == 22);
static_assert(sum[1] == 26);
static_assert(sum[2] == 30);
return 0;
}
注意:当将该函数移到头文件时,请不要忘记将static constexpr
替换为inline constexpr
。
英文:
You can still work with std::array at compile time since it is constexpr friendly (C++17 also). So the building block for working with arrays at compile time is still std::array. So I see no need to work through the extra complexity of template arguments for your values, and then the solution looks like this:
#include <array>
template<typename type_t, std::size_t N, std::size_t M>
static constexpr auto sum_arrays(const std::array<std::array<type_t, M>, N>& arrays)
{
std::array<type_t, M> sum{};
for (const auto& array : arrays)
{
for (std::size_t index{}; index < M; ++index)
{
sum[index] += array[index];
}
}
return sum;
}
int main()
{
static constexpr std::array<std::array<int, 3>, 4> arrays
{{
{1,2,3},
{4,5,6},
{7,8,9},
{10,11,12}
}};
static constexpr auto sum = sum_arrays(arrays);
static_assert(sum[0] == 22);
static_assert(sum[1] == 26);
static_assert(sum[2] == 30);
return 0;
}
Note : do not forget to replace static constexpr
with inline constexpr
when moving the function to a header file.
答案2
得分: 0
你可以简单地使用模板部分特化来实现这个:
#include <type_traits>
template <int... I>
struct Seq {};
template <typename... Seqs >
struct addSeq { };
template <typename X, typename Y, typename... Rest>
struct addSeq<X, Y, Rest...> : addSeq<typename addSeq<X, Y>::type, Rest...> { };
template <int... Xs, int... Ys>
struct addSeq<Seq<Xs...>, Seq<Ys...>> {
using type = Seq<(Xs + Ys)...>;
};
static_assert(std::is_same_v<addSeq<Seq<1, 2, 3>, Seq<2, 4, 6>, Seq<3, 6, 9>>::type, Seq<6, 12, 18>>);
英文:
You can simply use template partial specialization to do this:
#include <type_traits>
template <int... I>
struct Seq {};
template <typename...Seqs >
struct addSeq { };
template <typename X, typename Y, typename... Rest>
struct addSeq<X, Y, Rest...> : addSeq<typename addSeq<X, Y>::type, Rest...> { };
template <int... Xs, int... Ys>
struct addSeq<Seq<Xs...>, Seq<Ys...>> {
using type = Seq<(Xs + Ys)...>;
};
static_assert(std::is_same_v<addSeq<Seq<1, 2, 3>,Seq<2, 4, 6>, Seq<3, 6, 9> >::type, Seq<6, 12, 18>>);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论