锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

MyTinySTL阅读笔记---仿函数和配接器

时间:2023-04-26 16:37:01 w轴向位移变送器配接ws

文章目录

  • 仿函数
    • 为什么不使用函数指针呢?
    • 根据参数的数量进行分类
      • 一元仿函数
      • 二元仿函数
    • 按功能分类
      • 算术运算
      • 关系运算
      • 逻辑运算
      • 同样,选择,投影
  • MyTinySTL仿函数
  • 配接器

仿函数

所谓仿函数就是函数对象, 以前叫它, 只是一直沿用到现在。
仿函数是具有函数特征的对象.。
可以通过用户自己定义部分操作,然后输入
自定义函数名来调用。

为什么不使用函数指针呢?

  • 不能满足函数指针STL的抽象性
  • 函数指针不能与STL其它组件搭配, 不够灵活
  • 仿函数具有可匹配性, 可以满足traits编程, 也可以在编译期间完成, 没有运营费用

根据参数的数量进行分类

一元仿函数

一元仿函数基类:

template <class Arg, class Result> struct unary_function { 
             typedef Arg argument_type; // 参数类型别名     typedef Result result_type; // 返回值类型别名 }; 

二元仿函数

二元仿函数基类:

template <class Arg1, class Arg2, class Result> struct binary_function { 
             typedef Arg1 first_argument_type; // 参数类型别名     typedef Arg2 second_argument_type; // 参数类型别名     typedef Result result_type; // 返回值类型别名 };  

按功能分类

算术运算

如加法:

template <class T> struct plus : public binary_function<T, T, T> { 
             T operator()(const T& x, const T& y) const { 
         return x   y; } 
       
        }
        ; 
       

关系运算

如等于:

template <class T>
struct equal_to : public binary_function<T, T, bool> { 
        
    bool operator()(const T& x, const T& y) const { 
         return x == y; }
};

逻辑运算

如与:

template <class T>
struct logical_and : public binary_function<T, T, bool> { 
        
    bool operator()(const T& x, const T& y) const { 
         return x && y; }
};

正同,选择,投射

  • 正同 : 任何数值调用该函数都不会有改变
template <class T>
struct identity : public unary_function<T, T> { 
        
  const T& operator()(const T& x) const { 
         return x; }
};
  • 选择 : 接受一个pair类型, 并且返回第一个元素或者第二个元素
// 选择第一个元素
template <class Pair>
struct select1st : public unary_function<Pair, typename Pair::first_type> { 
        
  const typename Pair::first_type& operator()(const Pair& x) const
  { 
        
    return x.first;
  }
};
// 选择第二个元素
template <class Pair>
struct select2nd : public unary_function<Pair, typename Pair::second_type> { 
        
  const typename Pair::second_type& operator()(const Pair& x) const
  { 
        
    return x.second;
  }
};
  • 投影 : 接受一个pair类型, 忽略第二个元素返回第一个元素或者忽略第一个元素返回第二个元素
// 忽略第二个元素返回第一个元素
template <class Arg1, class Arg2>
struct project1st : public binary_function<Arg1, Arg2, Arg1> { 
        
  Arg1 operator()(const Arg1& x, const Arg2&) const { 
         return x; }
};
// 忽略第一个元素返回第二个元素
template <class Arg1, class Arg2>
struct project2nd : public binary_function<Arg1, Arg2, Arg2> { 
        
  Arg2 operator()(const Arg1&, const Arg2& y) const { 
         return y; }
};

MyTinySTL仿函数

涉及到的文件functional.h。
代码和上面介绍的一模一样,我就不贴了。

文件中还有个哈希函数对象,对于整型类型可以看到都是返回原值。

template <class Key>
struct hash { 
        };

/*! 哈希函数对象 针对指针的偏特化版本 返回指针的值 */
template <class T>
struct hash<T*>
{ 
        
	size_t operator()(T* p) const noexcept
	{ 
        
		return reinterpret_cast<size_t>(p);
	}
};

/*! 哈希函数对象 对于整型类型,只是返回原值 */
#define MYSTL_TRIVIAL_HASH_FCN(Type) \ template <> struct hash<Type> \ { 
           \ size_t operator()(Type val) const noexcept \ { 
           return static_cast<size_t>(val); } \ };

MYSTL_TRIVIAL_HASH_FCN(bool)

MYSTL_TRIVIAL_HASH_FCN(char)

MYSTL_TRIVIAL_HASH_FCN(signed char)

MYSTL_TRIVIAL_HASH_FCN(unsigned char)

MYSTL_TRIVIAL_HASH_FCN(wchar_t)

MYSTL_TRIVIAL_HASH_FCN(char16_t)

MYSTL_TRIVIAL_HASH_FCN(char32_t)

MYSTL_TRIVIAL_HASH_FCN(short)

MYSTL_TRIVIAL_HASH_FCN(unsigned short)

MYSTL_TRIVIAL_HASH_FCN(int)

MYSTL_TRIVIAL_HASH_FCN(unsigned int)

MYSTL_TRIVIAL_HASH_FCN(long)

MYSTL_TRIVIAL_HASH_FCN(unsigned long)

MYSTL_TRIVIAL_HASH_FCN(long long)

MYSTL_TRIVIAL_HASH_FCN(unsigned long long)

#undef MYSTL_TRIVIAL_HASH_FCN

对于浮点类型是逐位哈希。

/** * @brief 逐位哈希 * @param[in] first 数据地址 * @param[in] count 数据位数 */
inline size_t bitwise_hash(const unsigned char* first, size_t count)
{ 
        
#if (_MSC_VER && _WIN64) || ((__GNUC__ || __clang__) &&__SIZEOF_POINTER__ == 8)
	const size_t fnv_offset = 14695981039346656037ull;
	const size_t fnv_prime = 1099511628211ull;
#else
	const size_t fnv_offset = 2166136261u;
	const size_t fnv_prime = 16777619u;
#endif
	size_t result = fnv_offset;
	for (size_t i = 0; i < count; ++i)
	{ 
        
		result ^= (size_t)first[i];
		result *= fnv_prime;
	}
	return result;
}

/*! 哈希函数对象 对于浮点数,逐位哈希 */
template <>
struct hash<float>
{ 
        
	size_t operator()(const float& val)
	{ 
        
		return val == 0.0f ? 0 : bitwise_hash((const unsigned char*)&val, sizeof(float));
	}
};

/*! 哈希函数对象 对于浮点数,逐位哈希 */
template <>
struct hash<double>
{ 
        
	size_t operator()(const double& val)
	{ 
        
		return val == 0.0f ? 0 : bitwise_hash((const unsigned char*)&val, sizeof(double));
	}
};

/*! 哈希函数对象 对于浮点数,逐位哈希 */
template <>
struct hash<long double>
{ 
        
	size_t operator()(const long double& val)
	{ 
        
		return val == 0.0f ? 0 : bitwise_hash((const unsigned char*)&val, sizeof(long double));
	}
};

配接器

主要用来修改接口。就像转接口一样, 将一个对class封装变成了另外一个功能的class。

STL 主要提供如下三种配接器:

  1. 改变仿函数(functors)接口,称之为 function adapter
  2. 改变容器(containers)接口,称之位 container adapter
  3. 改变迭代器(iterators)接口者,称之为 iterator adapter
锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章