如何解决如何使用range :: sort进行由布尔值控制的升序或降序排序
使用范围使我可以减少样板,所以效果很好,但是我找不到以升序或降序排序的方法。 以下代码段可以很好地进行编译(g ++ 10.2.0),而投影确实可以简化代码,而无需使用lambda。
struct Player {
double score_;
string name_;
};
vector<Player> players{
{10.0,"Thorin"},{20.0,"Bombur"},{15.0,"Bofur"},{5.0,"Bifur"},{ 2.0,"Balin"},{25.0,"Kili" },{23.0,"Fili"},{4.0,"Dwalin"}
};
std::ranges::sort(players,std::ranges::less{},&Player::score_ );
for(auto const &player : players) {
cout << "Name = " << std::left << setw(10) << player.name_
<< " Score = " << player.score_ << endl;
}
现在我需要一个布尔值来控制升序或降序排序。
我想写一个像这样的简单语句:
std::ranges::sort(players,sort_ascending ? std::ranges::less() : std::ranges::greater(),&Player::score_);
但是std::ranges::less
和std::ranges::greater
的类型不同,因此三元运算符将不起作用。
error: operands to ‘?:’ have different types ‘std::ranges::less’ and ‘std::ranges::greater’
我可能会在下面显示捕获的lambda,但这会增加更多的代码行。 有什么简单的解决方案吗?
auto mycompare = [sort_ascending](
const Player &a,const Player &b) -> bool {
return sort_ascending ^ (b.score_ < a.score_);
};
std::ranges::sort(players,mycompare);
解决方法
如果sort_ascending
是运行时布尔值,那么我认为不可能在对sort
的调用内 中选择其他函数对象,因为必须在编译时知道该对象的类型。
一个选择是重构它,并增加几行:
auto sort_if = [] (bool sort_ascending,auto &range,auto proj)
{
if (sort_ascending)
std::ranges::sort(range,std::ranges::less{},proj);
else
std::ranges::sort(range,std::ranges::greater{},proj);
};
并这样称呼它:
sort_if(sort_ascending,players,&Player::score_);
此外,请注意,如果sort_ascending
为假,则最后一个代码段将被破坏。谓词最终将是std::less
的否定,它是std::greater_equal
,而不是std::greater
。这违反了sort
所要求的严格弱排序,最终导致未定义的行为。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。