std::vector 的 std::arrays 的比较函数
Comparison function for std::vector of std::arrays
我想处理大量双精度数组。所有数组的长度都相同。我决定使用 std::arrays 的 std::vector。对于数据缩放,我需要找到所有值的最小值和最大值。我认为我可以这样做的方法如下:
#include <algorithm>
#include <vector>
#include <array>
class ChannelData {
...
template<std::size_t N>
bool static compareX(std::array<double, m_nelem> const& a, std::array<double, m_nelem> const& b) {
return a[N] < b[N];
}
std::vector<std::array<double, m_nelem> > m_data;
std::array<<std::array<double, 2> m_nelem> m_minmax;
void find_minmax_x(){
for (int i = 0; i < m_nelem; i++){
auto minmax = std::minmax_element(m_data.begin(), m_data.end(), compareX<i>);
m_minmax[i][0] = (*minmax.first)[i];
m_minmax[i][1] = (*minmax.second)[i];
}
}
这不编译。那是因为我用来在函数 find_minmax_x
中实例化 compareX<N>
的非类型参数 i
不是常量表达式。
据我了解,编译器不知道在编译时要实例化哪些版本,即使在这种情况下它是相当明显的。我最终做的是手动展开 for 循环,但这很丑陋。你能推荐一种更美观的方法来完成这个吗?
struct compareX {
std::size_t N;
bool operator()(std::array<double, m_nelem> const& a, std::array<double, m_nelem> const& b) const {
return a[N] < b[N];
}
};
...
void find_minmax_x(){
for (int i = 0; i < m_nelem; i++){
auto minmax = std::minmax_element(m_data.begin(), m_data.end(), compareX{i});
m_minmax[i][0] = (*minmax.first)[i];
m_minmax[i][1] = (*minmax.second)[i];
}
}
如果您的值不是编译时值,请不要将其作为模板非类型参数传递。储存起来。
std
算法将像使用函数指针一样轻松地使用可调用对象。
compareX
写得乱七八糟有点烦人。我们可以内联移动它:
void find_minmax_x(){
for (int i = 0; i < m_nelem; i++){
auto compareX = [i](std::array<double, m_nelem> const& a, std::array<double, m_nelem> const& b) {
return a[i] < b[i];
};
auto minmax = std::minmax_element(m_data.begin(), m_data.end(), compareX);
m_minmax[i][0] = (*minmax.first)[i];
m_minmax[i][1] = (*minmax.second)[i];
}
}
这里有点冗长,因为所讨论的类型非常多。在 C++14 中,我们取消了那些巨大的类型并得到:
void find_minmax_x(){
for (int i = 0; i < m_nelem; i++){
auto compareX = [&](auto&& a, auto&& b) {
return a[i] < b[i];
};
auto minmax = std::minmax_element(m_data.begin(), m_data.end(), compareX);
m_minmax[i][0] = (*minmax.first)[i];
m_minmax[i][1] = (*minmax.second)[i];
}
}
它会自动创建一个可调用对象,其模板 operator()
通过引用捕获 i
。
我通常有一个投影order_by
比较:
template<class F, class O=std::less<>>
auto order_by( F&& f, O&& o = {} ) {
return [f = std::forward<F>(f), o = std::forward<O>(o)](auto&& lhs, auto&& rhs)->bool{
return o(f(lhs), f(rhs));
};
};
(又是 C++14,可以用 C++11 编写)这会将您的代码缩减为:
void find_minmax_x(){
for (int i = 0; i < m_nelem; i++){
auto minmax = std::minmax_element(
m_data.begin(), m_data.end(),
order_by([i](auto&&a){return a[i];})
);
m_minmax[i][0] = (*minmax.first)[i];
m_minmax[i][1] = (*minmax.second)[i];
}
}
我想处理大量双精度数组。所有数组的长度都相同。我决定使用 std::arrays 的 std::vector。对于数据缩放,我需要找到所有值的最小值和最大值。我认为我可以这样做的方法如下:
#include <algorithm>
#include <vector>
#include <array>
class ChannelData {
...
template<std::size_t N>
bool static compareX(std::array<double, m_nelem> const& a, std::array<double, m_nelem> const& b) {
return a[N] < b[N];
}
std::vector<std::array<double, m_nelem> > m_data;
std::array<<std::array<double, 2> m_nelem> m_minmax;
void find_minmax_x(){
for (int i = 0; i < m_nelem; i++){
auto minmax = std::minmax_element(m_data.begin(), m_data.end(), compareX<i>);
m_minmax[i][0] = (*minmax.first)[i];
m_minmax[i][1] = (*minmax.second)[i];
}
}
这不编译。那是因为我用来在函数 find_minmax_x
中实例化 compareX<N>
的非类型参数 i
不是常量表达式。
据我了解,编译器不知道在编译时要实例化哪些版本,即使在这种情况下它是相当明显的。我最终做的是手动展开 for 循环,但这很丑陋。你能推荐一种更美观的方法来完成这个吗?
struct compareX {
std::size_t N;
bool operator()(std::array<double, m_nelem> const& a, std::array<double, m_nelem> const& b) const {
return a[N] < b[N];
}
};
...
void find_minmax_x(){
for (int i = 0; i < m_nelem; i++){
auto minmax = std::minmax_element(m_data.begin(), m_data.end(), compareX{i});
m_minmax[i][0] = (*minmax.first)[i];
m_minmax[i][1] = (*minmax.second)[i];
}
}
如果您的值不是编译时值,请不要将其作为模板非类型参数传递。储存起来。
std
算法将像使用函数指针一样轻松地使用可调用对象。
compareX
写得乱七八糟有点烦人。我们可以内联移动它:
void find_minmax_x(){
for (int i = 0; i < m_nelem; i++){
auto compareX = [i](std::array<double, m_nelem> const& a, std::array<double, m_nelem> const& b) {
return a[i] < b[i];
};
auto minmax = std::minmax_element(m_data.begin(), m_data.end(), compareX);
m_minmax[i][0] = (*minmax.first)[i];
m_minmax[i][1] = (*minmax.second)[i];
}
}
这里有点冗长,因为所讨论的类型非常多。在 C++14 中,我们取消了那些巨大的类型并得到:
void find_minmax_x(){
for (int i = 0; i < m_nelem; i++){
auto compareX = [&](auto&& a, auto&& b) {
return a[i] < b[i];
};
auto minmax = std::minmax_element(m_data.begin(), m_data.end(), compareX);
m_minmax[i][0] = (*minmax.first)[i];
m_minmax[i][1] = (*minmax.second)[i];
}
}
它会自动创建一个可调用对象,其模板 operator()
通过引用捕获 i
。
我通常有一个投影order_by
比较:
template<class F, class O=std::less<>>
auto order_by( F&& f, O&& o = {} ) {
return [f = std::forward<F>(f), o = std::forward<O>(o)](auto&& lhs, auto&& rhs)->bool{
return o(f(lhs), f(rhs));
};
};
(又是 C++14,可以用 C++11 编写)这会将您的代码缩减为:
void find_minmax_x(){
for (int i = 0; i < m_nelem; i++){
auto minmax = std::minmax_element(
m_data.begin(), m_data.end(),
order_by([i](auto&&a){return a[i];})
);
m_minmax[i][0] = (*minmax.first)[i];
m_minmax[i][1] = (*minmax.second)[i];
}
}