gpt4 book ai didi

c++ - 基于成员字段或函数创建比较器的快捷方式

转载 作者:可可西里 更新时间:2023-11-01 15:46:14 24 4
gpt4 key购买 nike

我经常发现自己想要为 struct 创建一个比较器对象或 class它只是提取该类的一个成员并执行通常的 <比较。

例如:

struct student {
int id;
std::string name;
};

// sort by ID
std::sort(students.begin(), students.end(), [](const student& l, const student& r){ return l.id < r.id; });

那里有很多样板文件,特别是因为我们必须重复 l 的声明。和 r .标准库中有没有一种方法可以基于返回要比较的对象的“提取器”函数创建比较器?

类似于:

std::sort(students.begin(), students.end(), compare_on([](const student& s){ return s.id; });

我正在使用 C++11,但如果以后的标准中有不适用于 C++11 的解决方案,我也很感兴趣(这样我就可以在我的“升级原因”列表中添加一些内容)。

我在这里问的是关于使用单个成员作为 comprand,以及默认比较“小于”,但对于容易组合的技术,例如允许您按字典顺序使用两个字段,或更改比较运算符。

最佳答案

您有效地寻找的是允许将投影 传递到算法中。 N4128为标准库提出了这一点,C++20 将为许多算法提供这些。

但在那之前,我们可以自己做。编写一个新的 sort 重载:

struct identity {
template <typename T>
T&& operator()(T&& t) const noexcept { return std::forward<T>(t); }
};

// because no std::less<> in C++11 yet
struct less {
template <typename T, typename U>
constexpr bool operator()(T const& lhs, U const& rhs) const {
return lhs < rhs;
}
};

template <typename Range, typename Comp=less, typename Proj=identity>
void sort_proj(Range& range, Comp comp={}, Proj proj={}) {
using std::begin;
using std::end;
auto first = begin(range), last = end(range);
using reference = typename std::iterator_traits<decltype(first)>::reference;

std::sort(first, last,
[&](reference lhs, reference rhs) {
return comp(std::ref(proj)(lhs), std::ref(proj)(rhs));
});
}

std::ref(f)(x) 是在 C++11 中获得 INVOKE 功能的技巧。它基本上允许您将指针作为投影传递给成员。这个实现可以让你写:

sort_proj(students, less{}, &student::id);

请注意,投影与顺序无关。所以我可以很容易地做各种事情:

sort_proj(students);                            // sort on students, if they're ordered
sort_proj(students, greater{}, &student::name); // decreasing, by name
sort_proj(students, less{}, // by name, then id
[](student const& s) {
return std::tie(s.name, s.id);
});

这种方法 super 在消除一般算法中的大量样板文件方面非常有用。我有一个 header ,其中充满了许多常用标准算法的基于投影的重载。

关于c++ - 基于成员字段或函数创建比较器的快捷方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52191326/

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