我是靠谱客的博主 能干龙猫,最近开发中收集的这篇文章主要介绍std::less源码剖析一、关键点解析二、源码分析,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

目录

一、关键点解析

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

最后

以上就是能干龙猫为你收集整理的std::less源码剖析一、关键点解析二、源码分析的全部内容,希望文章能够帮你解决std::less源码剖析一、关键点解析二、源码分析所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(56)

评论列表共有 0 条评论

立即
投稿
返回
顶部