【问题标题】:How does `std::less` work?`std::less` 是如何工作的?
【发布时间】:2015-06-03 10:13:16
【问题描述】:

指针关系运算符不定义总顺序 (§ 5.9 of the C++11 standard):

如果两个相同类型的指针pq指向不同的对象,这些对象不是同一对象的成员或同一数组的元素或不同的函数,或者如果其中只有一个为空,则p<qp>qp<=qp>=q 的结果未指定。

std::less 文档说:

std::less 对任何指针类型的部分特化产生一个总顺序,即使内置的 operator< 没有。

它是如何从偏序产生这个全序的?


我无法通过查看 /usr/include/c++/4.9/bits/stl_function.h 中的 struct less 定义来回答这个问题:

  template<typename _Tp = void>
    struct less;

  template<typename _Tp>
    struct less : public binary_function<_Tp, _Tp, bool>
    {
      bool
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x < __y; }
    };

  template<>
    struct less<void>
    {
      template <typename _Tp, typename _Up>
        auto
        operator()(_Tp&& __t, _Up&& __u) const
        noexcept(noexcept(std::forward<_Tp>(__t) < std::forward<_Up>(__u)))
        -> decltype(std::forward<_Tp>(__t) < std::forward<_Up>(__u))
        { return std::forward<_Tp>(__t) < std::forward<_Up>(__u); }

      typedef __is_transparent is_transparent;
    };

【问题讨论】:

    标签: c++ c++11 stl relational partial-ordering


    【解决方案1】:

    它是如何从偏序产生这个全序的?

    标准很少说明如何完成某件事。相反,它说明了需要什么。而事实正是如此。该标准要求std::less 在§20.9.6/14 中提供总订单:

    对于更大、更少、greater_equal 和 less_equal 模板,任何指针类型的特化都会产生一个总顺序,即使内置运算符 、= 没有。

    虽然operator&lt; 在这方面的行为是未指定 根据§5.9/4(您在问题中的引用)。

    未指定的行为在 §1.3.25 中定义为:

    行为,对于格式良好的程序结构和正确的数据,取决于实现 [...]

    在您的具体实现中,operator&lt; 已经提供了总顺序(可能是因为您的指针类型实现为 32 位或 64 位地址,可以很容易地解释为类似于无符号整数的东西,产生总顺序),因此std::less 只是将其参数转发给该运算符。

    【讨论】:

    • 谢谢,你的回答很完美。但是,您是否知道任何不提供总订单的operator&lt; 实现? std::less 实现如何从中产生总订单?
    • @rom1v 我不知道这种实现的存在。我很确定它存在,考虑到标准委员会如何谨慎地决定什么是要求,什么是未指定的行为
    • 我不确定它是否仍然存在。其中大部分来自远近指针的时代。
    • 可能是为在旧的“真实”模式下运行的 x86 处理器提供分段内存(请参阅en.wikipedia.org/wiki/X86_memory_segmentation
    猜你喜欢
    • 2015-12-20
    • 2013-06-15
    • 2012-12-15
    • 2017-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多