【问题标题】:How to use ranges::sort for ascending or descending sort controlled by a boolean如何使用 range::sort 进行由布尔值控制的升序或降序排序
【发布时间】:2021-01-26 13:07:00
【问题描述】:

使用范围让我可以减少样板文件,所以这很好,但我找不到按升序或降序排序的方法。 以下 sn-p 编译得很好(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::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);

【问题讨论】:

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


    【解决方案1】:

    如果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 为假,则您的最后一个 sn-p 已损坏。谓词最终会否定std::less,即std::greater_equal,而不是std::greater。这违反了sort 所要求的严格-弱排序,您最终会出现未定义的行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-03
      • 1970-01-01
      • 2017-06-10
      • 2013-09-10
      • 1970-01-01
      • 2022-01-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多