使用范围允许我减少样板文件,所以这很好,但我找不到按升序或降序排序的方法。
以下代码段编译得很好(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;
}
现在我需要一个 bool 控制升序或降序排序。我想写一个这样的简单语句:
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
是一个运行时 bool 值,那么我认为不可能在对 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
要求的严格弱排序,你最终会得到未定义的行为。
关于c++ - 如何使用 range::sort 进行由 bool 值控制的升序或降序排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64314120/