以下代码定义了任意类型的operator+between std::array。该实现包括定义一个辅助例程op2,该例程采用通用可调用运算符,并通过模板递归将其应用于数组的每个元素。
#include <array>
#include <functional>
#include <iostream>
template <typename T, std::size_t N>
std::array<T, N> operator+(const std::array<T, N>& lhs, const std::array<T, N>& rhs);
template <std::size_t Index = 0, typename T, std::size_t N, class F>
void op2(const std::array<T, N>& lhs, const std::array<T, N>& rhs, std::array<T, N>& res, F&& op);
template <typename T, std::size_t N>
std::array<T, N> operator+(const std::array<T, N>& lhs, const std::array<T, N>& rhs)
{
std::array<T, N> res;
op2(lhs, rhs, res, std::plus{});
return res;
}
template <std::size_t Index, typename T, std::size_t N, class F>
void op2(const std::array<T, N>& lhs, const std::array<T, N>& rhs, std::array<T, N>& res, F&& op)
{
std::get<Index>(res) = op(std::get<Index>(lhs), std::get<Index>(rhs));
if constexpr (Index < (N - 1))
op2<Index + 1>(lhs, rhs, res, std::forward<F>(op));
}
template <std::size_t N>
void print_array(const std::array<int, N>& a)
{
for (int x : a)
std::cout << x << ' ';
std::cout << '\n';
}
int main(){
std::array<int, 3> a{1, 2, 3};
std::array<int, 3> b{2, 2, 1};
print_array(a + b);
std::array<std::array<int, 3>, 2> c{a, b};
std::array<std::array<int, 3>, 2> d{a, b};
auto x = c + d; // Error: no match for call to std::plus<void>
return 0;
}
Run Code Online (Sandbox Code Playgroud)
看到它住在Coliru。
第一部分工作正常并计算 inta和数组的总和b。
接下来,c和d是std::array的std::array<int,3>。程序无法编译,因为它无法std::plus在c和 的组件之间找到匹配项d,即std::plus::operator()无法理解如何对 2 求和std::array<int, 3>。
一种解决方法是定义operator+为
template <typename T, std::size_t N>
std::array<T, N> operator+(const std::array<T, N>& lhs, const std::array<T, N>& rhs)
{
std::array<T, N> res;
op2(lhs, rhs, res, [](const auto& lhs, const auto& rhs) { return lhs + rhs; });
return res;
}
Run Code Online (Sandbox Code Playgroud)
看到它住在Coliru。
根据引用 std::plus=std::plus<void>应该简单地返回带有参数和返回类型推导的总和结果,与匿名 lambda 所做的非常相似。
为什么用的解决方案std::plus不编译?
| 归档时间: |
|
| 查看次数: |
101 次 |
| 最近记录: |