Dan*_*nra 10 c++ arrays templates c++11
请考虑以下事项:(Wandbox)
#include <array>
#include <algorithm>
#include <iostream>
template<typename T, int N, int M>
auto concat(const std::array<T, N>& ar1, const std::array<T, M>& ar2)
{
std::array<T, N+M> result;
std::copy (ar1.cbegin(), ar1.cend(), result.begin());
std::copy (ar2.cbegin(), ar2.cend(), result.begin() + N);
return result;
}
int main()
{
std::array<int, 3> ar1 = {1, 2, 3};
std::array<int, 2> ar2 = {4, 5};
auto result = concat<int, 3, 2>(ar1, ar2);
for (auto& x : result)
std::cout << x << " ";
std::cout << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
给定一个,, ... 的序列std::array<T, length1>,我如何推广上面的代码并编写一个将序列连接成一个函数的函数?std::array<T, length2>std::array<T, lengthK>std::array<T, sum(lengths)>
如果有一种方法可以编写一个可重用的函数,使用给定的二进制操作减少类似的模板类序列,例如,concat在上面的例子中使用,而不是编写一个特殊的方法(必须重新编写),这将是很好的.每次二进制op改变时写入).
(IIUC,相关的标准库算法(accumulate,reduce)仅适用于二进制操作的结果类始终相同的情况.)
您可以执行以下操作:
template <typename F, typename T, typename T2>
auto func(F f, T&& t, T2&& t2)
{
return f(std::forward<T>(t), std::forward<T2>(t2));
}
template <typename F, typename T, typename T2, typename ... Ts>
auto func(F f, T&& t, T2&& t2, Ts&&...args)
{
return func(f, f(std::forward<T>(t), std::forward<T2>(t2)), std::forward<Ts>(args)...);
}
Run Code Online (Sandbox Code Playgroud)
随着使用
struct concatenater
{
template<typename T, std::size_t N, std::size_t M>
auto operator()(const std::array<T, N>& ar1, const std::array<T, M>& ar2) const
{
std::array<T, N+M> result;
std::copy (ar1.cbegin(), ar1.cend(), result.begin());
std::copy (ar2.cbegin(), ar2.cend(), result.begin() + N);
return result;
}
};
Run Code Online (Sandbox Code Playgroud)
和
auto result = func(concatenater{}, ar1, ar2, ar3, ar4);
Run Code Online (Sandbox Code Playgroud)
给定一系列的
std::array<T, length1>,,std::array<T, length2>...,std::array<T, lengthK>我怎样才能编写一个将序列连接成一个函数的函数std::array<T, sum(lengths)>?
这是一个C++ 17解决方案.它很可能会缩短和改进,正在努力.
template <std::size_t Last = 0, typename TF, typename TArray, typename... TRest>
constexpr auto with_acc_sizes(TF&& f, const TArray& array, const TRest&... rest)
{
f(array, std::integral_constant<std::size_t, Last>{});
if constexpr(sizeof...(TRest) != 0)
{
with_acc_sizes<Last + std::tuple_size_v<TArray>>(f, rest...);
}
}
template<typename T, std::size_t... Sizes>
constexpr auto concat(const std::array<T, Sizes>&... arrays)
{
std::array<T, (Sizes + ...)> result{};
with_acc_sizes([&](const auto& arr, auto offset)
{
std::copy(arr.begin(), arr.end(), result.begin() + offset);
}, arrays...);
return result;
}
Run Code Online (Sandbox Code Playgroud)
用法:
std::array<int, 3> ar1 = {1, 2, 3};
std::array<int, 2> ar2 = {4, 5};
std::array<int, 3> ar3 = {6, 7, 8};
auto result = concat(ar1, ar2, ar3);
Run Code Online (Sandbox Code Playgroud)
适用于g ++ 7和clang ++ 5.
这是一个通过折叠表达式的简单 C++17 解决方案:
#include <array>
#include <algorithm>
template <typename Type, std::size_t... sizes>
auto concatenate(const std::array<Type, sizes>&... arrays)
{
std::array<Type, (sizes + ...)> result;
std::size_t index{};
((std::copy_n(arrays.begin(), sizes, result.begin() + index), index += sizes), ...);
return result;
}
Run Code Online (Sandbox Code Playgroud)
使用示例:
const std::array<int, 3> array1 = {{1, 2, 3}};
const std::array<int, 2> array2 = {{4, 5}};
const std::array<int, 4> array3 = {{6, 7, 8, 9}};
const auto result = concatenate(array1, array2, array3);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
759 次 |
| 最近记录: |