Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/utility/functional/mem fn"

From cppreference.com
< cpp‎ | utility‎ | functional
(tabs fixed)
(not "tentatively ready", but accepted into 14)
Line 7: Line 7:
 
/*unspecified*/ mem_fn(R T::* pm);
 
/*unspecified*/ mem_fn(R T::* pm);
 
}}
 
}}
{{ddcl list item | notes={{mark | c++11, but defect}} | num=2 |
+
{{ddcl list item | notes={{mark until c++14}} | num=2 |
 
template< class R, class T, class... Args >  
 
template< class R, class T, class... Args >  
 
/*unspecified*/ mem_fn(R (T::* pm)(Args...));
 
/*unspecified*/ mem_fn(R (T::* pm)(Args...));
Line 37: Line 37:
 
Function template {{tt|std::mem_fn}} generates wrapper objects for pointers to members, which can store, copy, and invoke a pointer to member. Both references and pointers (including smart pointers) to an object can be used when invoking a {{tt|std::mem_fn}}.
 
Function template {{tt|std::mem_fn}} generates wrapper objects for pointers to members, which can store, copy, and invoke a pointer to member. Both references and pointers (including smart pointers) to an object can be used when invoking a {{tt|std::mem_fn}}.
  
The overloads (2) are reported as defect.
+
The overloads (2) were introduced in C++11 but removed in C++14 as [http://cplusplus.github.io/LWG/lwg-defects.html#2048 defect #2048]
The [http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2012/n3357.html#2048 resolution], which has recently been voted "Tentatively Ready" proposes to remove all the overloads (2).
+
This will break some code, see Example 3.
+
  
 
===Parameters===
 
===Parameters===
Line 144: Line 142:
 
===Example 3===
 
===Example 3===
 
{{example
 
{{example
  |
+
  | demonstrated the effect of the C++14 changes to the specification
 
  | code=
 
  | code=
  
Line 162: Line 160:
 
{
 
{
 
     auto a = std::mem_fn        (&X::easy); // no problem at all
 
     auto a = std::mem_fn        (&X::easy); // no problem at all
//  auto b = std::mem_fn<int&  >(&X::get ); // no longer works with new specification
+
//  auto b = std::mem_fn<int&  >(&X::get ); // no longer works in C++14
     auto c = std::mem_fn<int&()>(&X::get ); // works with both old and new specification
+
     auto c = std::mem_fn<int&()>(&X::get ); // works with both C++11 and C++14
 
     auto d = [] (X& x) {return x.get();};  // another approach to overload resolution
 
     auto d = [] (X& x) {return x.get();};  // another approach to overload resolution
 
      
 
      

Revision as of 20:18, 15 May 2013

 
 
Utilities library
General utilities
Relational operators (deprecated in C++20)
 
Function objects
Function invocation
(C++17)(C++23)
Identity function object
(C++20)
Transparent operator wrappers
(C++14)
(C++14)
(C++14)
(C++14)  
(C++14)
(C++14)
(C++14)
(C++14)
(C++14)
(C++14)
(C++14)
(C++14)
(C++14)

Old binders and adaptors
(until C++17*)
(until C++17*)
(until C++17*)
(until C++17*)  
(until C++17*)
(until C++17*)(until C++17*)(until C++17*)(until C++17*)
(until C++20*)
(until C++20*)
(until C++17*)(until C++17*)
(until C++17*)(until C++17*)

(until C++17*)
(until C++17*)(until C++17*)(until C++17*)(until C++17*)
(until C++20*)
(until C++20*)
 

Template:ddcl list begin <tr class="t-dsc-header">

<td>
Defined in header <functional>
</td>

<td></td> <td></td> </tr> <tr class="t-dcl ">

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

<td > (1) </td> <td > (since C++11) </td> </tr> <tr class="t-dcl ">

<td >
template< class R, class T, class... Args >

/*unspecified*/ mem_fn(R (T::* pm)(Args...));
template< class R, class T, class... Args >
/*unspecified*/ mem_fn(R (T::* pm)(Args...) const);
template< class R, class T, class... Args >
/*unspecified*/ mem_fn(R (T::* pm)(Args...) volatile);
template< class R, class T, class... Args >
/*unspecified*/ mem_fn(R (T::* pm)(Args...) const volatile);
template< class R, class T, class... Args >
/*unspecified*/ mem_fn(R (T::* pm)(Args...) &);
template< class R, class T, class... Args >
/*unspecified*/ mem_fn(R (T::* pm)(Args...) const &);
template< class R, class T, class... Args >
/*unspecified*/ mem_fn(R (T::* pm)(Args...) volatile &);
template< class R, class T, class... Args >
/*unspecified*/ mem_fn(R (T::* pm)(Args...) const volatile &);
template< class R, class T, class... Args >
/*unspecified*/ mem_fn(R (T::* pm)(Args...) &&);
template< class R, class T, class... Args >
/*unspecified*/ mem_fn(R (T::* pm)(Args...) const &&);
template< class R, class T, class... Args >
/*unspecified*/ mem_fn(R (T::* pm)(Args...) volatile &&);
template< class R, class T, class... Args >

/*unspecified*/ mem_fn(R (T::* pm)(Args...) const volatile &&);
</td>

<td > (2) </td> <td > (until C++14) </td> </tr> Template:ddcl list end

Function template std::mem_fn generates wrapper objects for pointers to members, which can store, copy, and invoke a pointer to member. Both references and pointers (including smart pointers) to an object can be used when invoking a std::mem_fn.

The overloads (2) were introduced in C++11 but removed in C++14 as defect #2048

Contents

Parameters

pm - pointer to member that will be wrapped

Return value

std::mem_fn returns an call wrapper of unspecified type that has the following members:

std::mem_fn Return type

Member types

type definition
result_type the return type of pm if pm is a pointer to member function, not defined for pointer to member object
argument_type T*, possibly cv-qualified, if pm is a pointer to member function taking no arguments
first_argument_type T* if pm is a pointer to member function taking one argument
second_argument_type T1 if pm is a pointer to member function taking one argument of type T1

Member function

operator()
invokes the target on a specified object, with optional parameters
(public member function)

Exceptions

None.

Example 1

Use mem_fn to store and execute a member function and a member object:

#include <functional>
#include <iostream>
 
struct Foo {
    void display_greeting() {
        std::cout << "Hello, world.\n";
    }
    void display_number(int i) {
        std::cout << "number: " << i << '\n';
    }
    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) << '\n';
}

Output:

Hello, world.
number: 42
data: 7

Example 2

Pass a member function to std::transform to create a sequence of numbers:

#include <iostream>
#include <functional>
#include <iterator>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
 
int main()
{
    std::vector<std::string> words = {"This", "is", "a", "test"};
    std::vector<std::unique_ptr<std::string>> words2;
    words2.emplace_back(new std::string("another"));
    words2.emplace_back(new std::string("test"));
 
    std::vector<std::size_t> lengths;
    std::transform(words.begin(),
                   words.end(),
                   std::back_inserter(lengths),
                   std::mem_fn(&std::string::size)); // uses references to strings
    std::transform(words2.begin(),
                   words2.end(),
                   std::back_inserter(lengths),
                   std::mem_fn(&std::string::size)); // uses unique_ptr to strings
 
    std::cout << "The string lengths are ";
    for(auto n : lengths) std::cout << n << ' ';
    std::cout << '\n';
}

Output:

The string lengths are 4 2 1 4 7 4

Example 3

demonstrated the effect of the C++14 changes to the specification

#include <iostream>
#include <functional>
 
struct X {
    int x;
 
    int&       easy()      {return x;}
    int&       get()       {return x;}
    const int& get() const {return x;}
};
 
 
int main(void)
{
    auto a = std::mem_fn        (&X::easy); // no problem at all
//  auto b = std::mem_fn<int&  >(&X::get ); // no longer works in C++14
    auto c = std::mem_fn<int&()>(&X::get ); // works with both C++11 and C++14
    auto d = [] (X& x) {return x.get();};   // another approach to overload resolution
 
    X x = {33};
    std::cout << "a() = " << a(x) << '\n';
    std::cout << "c() = " << c(x) << '\n';
    std::cout << "d() = " << d(x) << '\n';
}

Output:

a() = 33
c() = 33
d() = 33

See also

(C++11)
copyable wrapper of any copy constructible callable object
(class template) [edit]
(C++11)
binds one or more arguments to a function object
(function template) [edit]