ranges-v3 / 排序混乱

ranges-v3 / sort confusion

我似乎有点简单,因为我无法在下面标记为错误的行中清楚地看到此错误的原因。

std::sort 和 boost::sort 选择默认谓词,但 ranges-v3 出于某种原因没有选择。这是 ranges-v3 0.36。 clang 6/7 和 gcc 7/8 上的类似错误。

#include <range/v3/all.hpp>

#include <algorithm>
#include <boost/hana.hpp>
#include <utility>
#include <vector>
#include <boost/range/algorithm.hpp>


namespace hana = boost::hana;

template< typename T = int>
struct point_t {
  BOOST_HANA_DEFINE_STRUCT(point_t<T>, (T, x), (T, y));

  constexpr bool operator<(const point_t<T> &b) const noexcept {
    return hana::less(hana::to_tuple(*this), hana::to_tuple(b));
  };
};

int main() {

  std::vector<point_t<point_t<>>> all;

  boost::sort(all); // OK
  std::sort(std::begin(all), std::end(all)); //OK

  ranges::sort(all, std::less<point_t<point_t<>>>()); // OK
  ranges::sort(all, hana::less); // OK

  ranges::sort(all); // error no matching function for call to object of type 'const with_braced_init_args<ranges::v3::sort_fn>'

  return 0;
}

Casey 通过 range-v3 issue list 快速回答。

这是他要求的文字评论,而不是我放在这里的原始图片:

ranges::sort without a comparator argument requires the type to be sorted to model the StrictTotallyOrdered concept. That means the type must define all of ==, !=, <, >, <=, and >= with consistent semantcs.

我在那里回复了:

Thank you for getting back so quickly. I understand now. I must say it's a little disappointing it is incompatible with std::sort and boost::sort requirements. That is the price we pay for range-v3 loveliness I guess.

Thanks again, --Matt.

不幸的是,要求高于 std::sortboost::sort,因此代码 不会 工作。我理解动机。

出于好奇,std::rel_opsboost/operators 似乎干扰了我对可自省结构的聚合初始化支持的目标,所以遗憾的是我最终求助于宏(类似于下面)。

我会多玩一些,寻找更好的静态多态方案。

亲切的问候,

--马特

#define JEST_STRUCT(T)                                                         \
  constexpr bool operator==(const T &b) const noexcept {                       \
    return hana::equal(hana::to_tuple(*this), hana::to_tuple(b));              \
  };                                                                           \
                                                                               \
  constexpr bool operator!=(const T &b) const noexcept {                       \
    return hana::not_equal(hana::to_tuple(*this), hana::to_tuple(b));          \
  };                                                                           \
                                                                               \
  constexpr bool operator<(const T &b) const noexcept {                        \
    return hana::less(hana::to_tuple(*this), hana::to_tuple(b));               \
  };                                                                           \
                                                                               \
  constexpr bool operator<=(const T &b) const noexcept {                       \
    return hana::less_equal(hana::to_tuple(*this), hana::to_tuple(b));         \
  };                                                                           \
                                                                               \
  constexpr bool operator>(const T &b) const noexcept {                        \
    return hana::greater(hana::to_tuple(*this), hana::to_tuple(b));            \
  };                                                                           \
                                                                               \
  constexpr bool operator>=(const T &b) const noexcept {                       \
    return hana::greater_equal(hana::to_tuple(*this), hana::to_tuple(b));      \
  }