c++ - 如何使用 range::sort 进行由 bool 值控制的升序或降序排序

标签 c++ c++20 std-ranges

使用范围允许我减少样板文件,所以这很好,但我找不到按升序或降序排序的方法。
以下代码段编译得很好(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::lessstd::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/

相关文章:

c++ - 如何用 C++20 协程说 Hello World?

c++ - 约束和显式模板实例化

c++ - 为什么 views::reverse 可以将 non-sized_range 转换为 size_range?

c++ - 访问对象 unique_ptr 指向

c++ - "."、 "::"和 "->"之间的区别

c++ - 将 LEVEL 包含到 SysLog 日志文件中

c++ - 使用 C++20 遍历相等的范围

c++ - std::ranges::begin和std::begin之间有什么区别?

c++ - 使用 g++ 从 [-Wdangling-reference] 可能出现误报

c++ - 管理 Win32 应用程序和 QWinMigrate 之间的键盘事件