std::less源码剖析

这篇博客介绍了C++11及更高版本的关键特性,包括`noexcept`关键字用于异常处理,提升编译器优化,并给出使用建议。另外,解释了`__cplusplus`宏大于201103L表示C++11以上的版本,以及`less<void>`在C++11以上版本中的透明比较功能,允许不同类型的参数比较。同时,讨论了`is_transparent`的作用,以及右值引用的一个实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、关键点解析

1、noexcept

(1) 关键字noexcept

(2)有条件的noexcept

(3)noexcept使用建议

2、__cplusplus > 201103L

3、less

4、typedef __is_transparent is_transparent

5、右值引用例子

二、源码分析


一、关键点解析

1、noexcept

(1) 关键字noexcept

     从C++11开始,我们能看到很多代码当中都有关键字noexcept。比如下面使用了noexcept。

      constexpr test() noexcept
       { }

      该关键字告诉编译器,函数中不会发生异常,这有利于编译器对程序做更多的优化。
如果在运行时,noexecpt函数向外抛出了异常(如果函数内部捕捉了异常并完成处理,这种情况不算抛出异常),程序会直接终止,调用std::terminate()函数,该函数内部会调用std::abort()终止程序。

     C++中的异常处理是在运行时而不是编译时检测的。为了实现运行时检测,编译器创建额外的代码,然而这会妨碍程序优化。在实践中,一般两种异常抛出方式是常用的:

  • 一个操作或者函数可能会抛出一个异常;
  • 一个操作或者函数不可能抛出任何异常。

     后面这一种方式中在以往的C++版本中常用throw()表示,在C++ 11中已经被noexcept代替。

(2)有条件的noexcept

      noexcept 使用方式可以更加灵活,表明在一定条件下不发生异常。

 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); }

     它表示,如果操作std::forward<_Tp>(__t) > std::forward<_Up>(__u)不发生异常,那么函数template <typename _Tp, typename _Up> auto operator()(_Tp&& __t, _Up&& __u) const一定不发生异常。

(3)noexcept使用建议

      使用noexcept表明函数或操作不会发生异常,会给编译器更大的优化空间。强调一句,在不是以上情况或者没把握的情况下,不要轻易使用noexception。以下情形鼓励使用noexcept:

  • 移动构造函数(move constructor)
  • 移动分配函数(move assignment)
  • 析构函数(destructor)。
  • 叶子函数(Leaf Function)。叶子函数是指在函数内部不分配栈空间,也不调用其它函数,也不存储非易失性寄存器,也不处理异常。

2、__cplusplus > 201103L

      c++11为 201103L,less<void>能使用需要c++11以上不包括c++11,c++11不能使用less<void>。

3、less<void>

  /// One of the @link comparison_functors comparison functors@endlink.
  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;
    };

        operator()(_Tp&& __t, _Up&& __u)万能引用,具体请看std::forward和std::move源码分析_kupePoem的专栏-CSDN博客_forward一、forward源码 /** * @brief Forward an lvalue. * @return The parameter cast to the specified type. * * This function is used to implement "perfect forwarding". */ template<typename _Tp> constexpr _Tp&& forward(typhttps://blog.csdn.net/kupepoem/article/details/119948044

#include<iostream> 
int main()
{

	std::cout<<a;
	std::cout<<std::less<int>()(1,1.2);// 输出0  都需要转成int
	std::cout<<std::less<void>()(1,1.2);//输出1  接受不同的参数,不需要都转成int
	return 0;
}

4、typedef __is_transparent is_transparent

      The name is_transparent comes from STL's N3421 which added the "diamond operators" to C++14. A "transparent functor" is one which accepts any argument types (which don't have to be the same) and simply forwards those arguments to another operator. Such a functor happens to be exactly what you want for heterogeneous lookup in associative containers, so the type is_transparent was added to all the diamond operators and used as the tag type to indicate the new functionality should be enabled in associative containers.

5、右值引用例子

​
#include<iostream> 
int*f()
{
	return NULL;
}
int main()
{
	int *p=NULL;
	int*&& a=f();
	
	std::cout<<a;
	return 0;
}

​

二、源码分析

  /** @}  */

  // 20.3.3 comparisons
  /** @defgroup comparison_functors Comparison Classes
   * @ingroup functors
   *
   *  The library provides six wrapper functors for all the basic comparisons
   *  in C++, like @c <.
   *
   *  @{
   */
#if __cplusplus > 201103L
  template<typename _Tp = void>
    struct equal_to;

  template<typename _Tp = void>
    struct not_equal_to;

  template<typename _Tp = void>
    struct greater;

  template<typename _Tp = void>
    struct less;

  template<typename _Tp = void>
    struct greater_equal;

  template<typename _Tp = void>
    struct less_equal;
#endif

  /// One of the @link comparison_functors comparison functors@endlink.
  template<typename _Tp>
    struct equal_to : public binary_function<_Tp, _Tp, bool>
    {
      bool
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x == __y; }
    };

  /// One of the @link comparison_functors comparison functors@endlink.
  template<typename _Tp>
    struct not_equal_to : public binary_function<_Tp, _Tp, bool>
    {
      bool
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x != __y; }
    };

  /// One of the @link comparison_functors comparison functors@endlink.
  template<typename _Tp>
    struct greater : public binary_function<_Tp, _Tp, bool>
    {
      bool
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x > __y; }
    };

  /// One of the @link comparison_functors comparison functors@endlink.
  template<typename _Tp>
    struct less : public binary_function<_Tp, _Tp, bool>
    {
      bool
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x < __y; }
    };

  /// One of the @link comparison_functors comparison functors@endlink.
  template<typename _Tp>
    struct greater_equal : public binary_function<_Tp, _Tp, bool>
    {
      bool
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x >= __y; }
    };

  /// One of the @link comparison_functors comparison functors@endlink.
  template<typename _Tp>
    struct less_equal : public binary_function<_Tp, _Tp, bool>
    {
      bool
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x <= __y; }
    };

#if __cplusplus > 201103L
  /// One of the @link comparison_functors comparison functors@endlink.
  template<>
    struct equal_to<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;
    };

  /// One of the @link comparison_functors comparison functors@endlink.
  template<>
    struct not_equal_to<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;
    };

  /// One of the @link comparison_functors comparison functors@endlink.
  template<>
    struct greater<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;
    };

  /// One of the @link comparison_functors comparison functors@endlink.
  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;
    };

  /// One of the @link comparison_functors comparison functors@endlink.
  template<>
    struct greater_equal<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;
    };

  /// One of the @link comparison_functors comparison functors@endlink.
  template<>
    struct less_equal<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;
    };
#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kupeThinkPoem

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值