STL-functional-1

Function objects

函数对象是专门设计用于与函数语法相似的语法的对象。在C++中,这是通过在类中定义成员函数运算符()来实现的,例如:

struct myclass {
  int operator()(int a) {return a;}
} myobject;
int x = myobject (0);           // function-like syntax with object myobject 

它们通常用作函数的参数,例如传递给标准算法的predicatescomparison functions

Functions

These functions create objects of wrapper classes based on its arguments:

bind

simple(1)
template <class Fn, class... Args>  /* unspecified */ bind (Fn&& fn, Args&&... args);
with return type (2)
template <class Ret, class Fn, class... Args>  /* unspecified */ bind (Fn&& fn, Args&&... args);

绑定函数参数

返回一个基于fn的函数对象,但其参数绑定到args。

每个参数可以绑定到一个值,也可以是一个占位符:

-如果绑定到某个值,则调用返回的函数对象将始终使用该值作为参数。

-如果是占位符,则调用返回的函数对象会转发传递给调用的参数(占位符指定其序号的参数)。 调用返回的对象将返回与fn相同的类型,除非将特定的返回类型指定为Ret(2)(请注意,Ret是传递给此函数的参数无法隐式推导的唯一模板参数)。

返回对象的类型具有以下属性:

它的函数调用返回与fn相同的结果,其参数绑定到args。。。(或转发,用于占位符)。

对于(1),它可能有一个成员result_type:如果Fn是指向函数或成员函数类型的指针,则它被定义为其返回类型的别名。否则,如果存在这样的成员类型,则将其定义为Fn::result_type。

对于(2),它有一个成员result_type,定义为Ret的别名。

它是可移动构造的,如果它所有参数的类型都是可复制构造的,那么它也是可复制构造。两个构造函数都从不抛出,前提是没有Fn和Args衰变类型的相应构造函数。。。投

// bind example
#include <iostream>     // std::cout
#include <functional>   // std::bind

// a function: (also works with function object: std::divides<double> my_divide;)
double my_divide (double x, double y) {return x/y;}

struct MyPair {
  double a,b;
  double multiply() {return a*b;}
};

int main () {
  using namespace std::placeholders;    // adds visibility of _1, _2, _3,...

  // binding functions:
  auto fn_five = std::bind (my_divide,10,2);               // returns 10/2
  std::cout << fn_five() << '\n';                          // 5

  auto fn_half = std::bind (my_divide,_1,2);               // returns x/2
  std::cout << fn_half(10) << '\n';                        // 5

  auto fn_invert = std::bind (my_divide,_2,_1);            // returns y/x
  std::cout << fn_invert(10,2) << '\n';                    // 0.2

  auto fn_rounding = std::bind<int> (my_divide,_1,_2);     // returns int(x/y)
  std::cout << fn_rounding(10,3) << '\n';                  // 3

  MyPair ten_two {10,2};

  // binding members:
  auto bound_member_fn = std::bind (&MyPair::multiply,_1); // returns x.multiply()
  std::cout << bound_member_fn(ten_two) << '\n';           // 20

  auto bound_member_data = std::bind (&MyPair::a,ten_two); // returns ten_two.a
  std::cout << bound_member_data() << '\n';                // 10

  return 0;
}Output:
5
5
0.2
3
20
10

cref

reference (1)
template <class T>  reference_wrapper<const T> cref (const T& elem) noexcept;
copy (2)
template <class T>  reference_wrapper<const T> cref (reference_wrapper<T>& x) noexcept;
move (3)
template <class T>  void cref (const T&&) = delete;

构造const的reference_wrapper

构造一个具有适当reference_wrapper类型的对象,以保存对elem的const T引用。

如果参数本身是常量T(2)的reference_wrapper,则它会创建x的副本。

该函数调用正确的reference_wrapper构造函数。

// cref example
#include <iostream>     // std::cout
#include <functional>   // std::ref

int main () {
  int foo (10);

  auto bar = std::cref(foo);

  ++foo;

  std::cout << bar << '\n';

  return 0;
}

Output:

11

mem_fn

template <class Ret, class T>  /* unspecified */ mem_fn (Ret T::* pm);

将成员函数转换为函数对象

返回一个函数对象,其函数调用调用pm所指向的成员函数。

返回对象的类型具有以下属性:

它的函数调用将T类型的对象(或指向它的引用或指针)作为第一个参数,并将pm所采用的参数(如果有的话)作为附加参数。以fn作为第一个参数的这种调用的效果与调用fn.*pm(或(*fn).*pm,如果fn是指针),转发任何其他参数相同。

它有一个成员result_type,定义为Ret的别名(这是pm的返回类型)。

如果pm指向的成员不带参数,则它有一个成员argument_type,定义为T*的别名。

如果pm指向的成员采用一个参数,则其成员first_argument_type(定义为T*的别名)和成员second_argument_type(定义为由pm采用的参数的别名)。

它是可构造的,可构造的和可分配的。

// mem_fn example
#include <iostream>     // std::cout
#include <functional>   // std::mem_fn

struct int_holder {
  int value;
  int triple() {return value*3;}
};

int main () {
  int_holder five {5};

  // call member directly:
  std::cout << five.triple() << '\n';

  // same as above using a mem_fn:
  auto triple = std::mem_fn (&int_holder::triple);
  std::cout << triple(five) << '\n';

  return 0;
}Output:
15
15

not1

template <class Predicate>  unary_negate<Predicate> not1 (const Predicate& pred);

返回一元函数对象的否定

构造一个一元函数对象(一元否定类型),该对象返回与pred相反的值(由运算符返回!)。

它的定义与以下行为相同:

template <class Predicate> unary_negate<Predicate> not1 (const Predicate& pred)
{
  return unary_negate<Predicate>(pred);
}
// not1 example
#include <iostream>     // std::cout
#include <functional>   // std::not1
#include <algorithm>    // std::count_if

struct IsOdd {
  bool operator() (const int& x) const {return x%2==1;}
  typedef int argument_type;
};

int main () {
  int values[] = {1,2,3,4,5};
  int cx = std::count_if (values, values+5, std::not1(IsOdd()));
  std::cout << "There are " << cx << " elements with even values.\n";
  return 0;
}
// not1 example
#include <iostream>     // std::cout
#include <functional>   // std::not1
#include <algorithm>    // std::count_if

struct IsOdd {
  bool operator() (const int& x) const {return x%2==1;}
  typedef int argument_type;
};

int main () {
  int values[] = {1,2,3,4,5};
  int cx = std::count_if (values, values+5, std::not1(IsOdd()));
  std::cout << "There are " << cx << " elements with even values.\n";
  return 0;
}Output:
There are 2 elements with even values.

not2

template <class Predicate>  binary_negate<Predicate> not2 (const Predicate& pred);

返回二元函数对象对象的否定

构造一个二元函数对象(binary_enegate类型),该对象返回与pred相反的值(由运算符返回!)。 它的定义与以下行为相同:

template <class Predicate> binary_negate<Predicate> not2 (const Predicate& pred)
{
  return binary_negate<Predicate>(pred);
}
// not2 example
#include <iostream>     // std::cout
#include <functional>   // std::not2, std::equal_to
#include <algorithm>    // std::mismatch
#include <utility>      // std::pair

int main () {
  int foo[] = {10,20,30,40,50};
  int bar[] = {0,15,30,45,60};
  std::pair<int*,int*> firstmatch,firstmismatch;
  firstmismatch = std::mismatch (foo, foo+5, bar, std::equal_to<int>());
  firstmatch = std::mismatch (foo, foo+5, bar, std::not2(std::equal_to<int>()));
  std::cout << "First mismatch in bar is " << *firstmismatch.second << '\n';
  std::cout << "First match in bar is " << *firstmatch.second << '\n';
  return 0;
}
First mismatch in bar is 0
First match in bar is 30

ref

reference (1)
template <class T> reference_wrapper<T> ref (T& elem) noexcept;
copy (2)
template <class T> reference_wrapper<T> ref (reference_wrapper<T>& x) noexcept;
move (3)
 template <class T> void ref (const T&&) = delete;

构造reference_wrapper

构造一个具有适当reference_wrapper类型的对象来保存对elem的引用。

如果参数本身是reference_wrapper(2),则它会创建x的副本。

该函数调用正确的reference_wrapper构造函数。

// ref example
#include <iostream>     // std::cout
#include <functional>   // std::ref

int main () {
  int foo (10);

  auto bar = std::ref(foo);

  ++bar;

  std::cout << foo << '\n';

  return 0;
}Output:
11

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值