c++ 11 함수 대상:functional

31377 단어 c++11
4 주로 클래스 템플릿 std::function과 함수 템플릿 std::bind를 추가했습니다.std::function은 호출 가능한 대상의 wrapper로 함수, lambda 표현식,bind 표현식, 함수 대상, 구성원 함수 바늘, 구성원 변수 바늘을 포장할 수 있습니다.std::bind도 호출 가능한 대상의 wrapper입니다. 호출 가능한 대상의 일부 또는 모든 파라미터를 특정한 값으로 연결할 수 있습니다. 되돌아오는 값은 std::function에 의해 포장될 수 있습니다.

function


std::function에 의해 포장된 호출 가능한 대상은 std::function의 target이라고 하고 std::function는 target을 저장, 복사, 호출할 수 있습니다.만약 std::function이 target을 포함하지 않는다면, 호출할 때 std::bad 를 던집니다function_콜 예외.
template <class>
class function; /* undefined */
template <class R, class... Args>
class function<R(Args...)>;
 :

 result_type, target R

 
function() noexcept;
function(std::nullptr_t) noexcept;
function(const function& other);	
function(function&& other);
template <class F> function(F f);
1-2) 
3-4) /move target
5) std::mvoe(f) target

 
function& operator=(const function& other);
function& operator=(function&& other);
function& operator=(std::nullptr_t);
template <class F> 
function& operator=(F&& f);
template <class F> 
function& operator=(std::reference_wrapper<F> f) noexcept;
1)copy the target of other
2)move the target of other
3)drop the current target
4) target std::forward<F>(f)
5) target f ( ?)

explicit operator bool() const noexcept;
 target 

R operator()(Args... args) const;
 args target, , std::bad_function_call 

std::function 대상은nullptr와만 비교할 수 있습니다. 왜냐하면operator==와operator!=이 버전만 Operator bool ()가true일 경우,nullptr와 같습니다.

bind

template <class Fn, class... Args>
  /* unspecified */ bind (Fn&& fn, Args&&... args);
template <class Ret, class Fn, class... Args>
  /* unspecified */ bind (Fn&& fn, Args&&... args);

fn
Function object, pointer to function, reference to function,
pointer to member function, or pointer to data member.
Fn shall have a decay type which is move-constructible from fn.

args...
List of arguments to bind: either values, or placeholders.
The types in Args... shall have decay types which are move-constructible
from their respective arguments in args....
If for any argument, its decay type is a reference_wrapper,
it bounds to its referenced value instead.

Calling the returned object returns the same type as fn, unless a specific
return type is specified as Ret(note that Ret is the only template parameter
that cannot be implicitly deduced by the arguments passed to this function).

std::bind의 첫 번째 파라미터는 호출 가능한 대상이고 나머지 파라미터는 호출 가능한 대상의 파라미터입니다.만약 파라미터가 귀속될 필요가 없다면 std::placeholders의 상수로 대체합니다.namespace placeholders는 자리 표시자 대상 [1,... N]을 포함하고 N은 구체적으로 최대 크기를 결정합니다.구체적인 예를 보면 비교적 명확하다.
#include 
#include 

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() << '
'
; // 5 auto fn_half = std::bind (my_divide,_1,2); // returns x/2 std::cout << fn_half(10) << '
'
; // 5 auto fn_invert = std::bind (my_divide,_2,_1); // returns y/x std::cout << fn_invert(10,2) << '
'
; // 0.2 auto fn_rounding = std::bind<int> (my_divide,_1,_2); // returns int(x/y) std::cout << fn_rounding(10,3) << '
'
; // 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) << '
'
; // 20 auto bound_member_data = std::bind (&MyPair::a,ten_two); // returns ten_two.a std::cout << bound_member_data() << '
'
; // 10 return 0; }

호출 가능한 대상의 매개 변수를 변수에 연결하려면 변수의 값이 변합니다. std::bind가 되돌아오는 호출 가능한 대상 중 이 값도 상응하는 변화가 있습니다. std:ref와 std::cref를 사용해야 합니다.std::ref와 std::cref는 함수 템플릿, 반환 클래스 템플릿 std::referencewrapper의 대상,std::referencewrapper 내부에서 포인터로 연결해야 하는 변수를 가리키며 포인터를 통해 변수에 접근하고 변수의 값을 수정하면reference의 역할을 실현할 수 있다.예를 들면 다음과 같습니다.
#include 
#include 
 
void f(int& n1, int& n2, const int& n3)
{
    std::cout << "In function: " << n1 << ' ' << n2 << ' ' << n3 << '
'
; ++n1; // increments the copy of n1 stored in the function object ++n2; // increments the main()'s n2 // ++n3; // compile error } int main() { int n1 = 1, n2 = 2, n3 = 3; std::function<void()> bound_f = std::bind(f, n1, std::ref(n2), std::cref(n3)); n1 = 10; n2 = 11; n3 = 12; std::cout << "Before function: " << n1 << ' ' << n2 << ' ' << n3 << '
'
; bound_f(); std::cout << "After function: " << n1 << ' ' << n2 << ' ' << n3 << '
'
; }

그러나 bind 반환값이 호출될 때 std::ref와 std::cref가 가리키는 변수가 존재하지 않으면 정의되지 않은 행위가 발생할 수 있음을 주의해야 한다.

mem_fn


구성원 함수나 구성원 변수를 호출할 때 귀속 파라미터가 필요하지 않으면 std::memfn:
template 
/*unspecified*/ mem_fn(M T::* pm);

예를 들면 다음과 같습니다.
#include 
#include 
 
struct Foo {
    void display_greeting() {
        std::cout << "Hello, world.
"
; } void display_number(int i) { std::cout << "number: " << i << '
'
; } int data = 7; }; int main() { Foo f; auto greet = std::mem_fn(&Foo::display_greeting); greet(f); auto print_num = std::mem_fn(&Foo::display_number); print_num(f, 42); auto access_data = std::mem_fn(&Foo::data); std::cout << "data: " << access_data(f) << '
'
; }

std::mem_fn은 std::bind로 대체할 수 있습니다. 예를 들어 위에서도 사용할 수 있습니다.
auto greet = std::bind(&Foo::display_greeting, _1);
auto print_num = std::bind(&Foo::display_number, _1, _2);
auto access_data = std::bind(&Foo::data, _1);

참고 자료


cppreference.com cplusplus.com

좋은 웹페이지 즐겨찾기