Namespaces
Variants

std:: mem_fn

From cppreference.net
Utilities library
Function objects
Function invocation
(C++17) (C++23)
Identity function object
(C++20)
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++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* )
ヘッダーで定義 <functional>
template < class M, class T >
/* unspecified */ mem_fn ( M T :: * pm ) noexcept ;
(C++11以降)
(constexpr C++20以降)

関数テンプレート std::mem_fn はメンバへのポインタに対するラッパーオブジェクトを生成し、これは メンバへのポインタ を格納、コピー、呼び出しすることができます。 std::mem_fn の呼び出し時には、オブジェクトへの参照とポインタ(スマートポインタを含む)の両方を使用できます。

目次

パラメータ

pm - ラップされるメンバへのポインタ

戻り値

std::mem_fn は、以下のメンバーを持つ未規定の型の呼び出しラッパー fn を返します:

std::mem_fn 戻り値の型

メンバ型

type definition
result_type (C++17で非推奨) pm がメンバ関数へのポインタの場合の戻り値の型、メンバオブジェクトへのポインタでは定義されない
argument_type (C++17で非推奨) T* (cv修飾される可能性あり)、 pm が引数を取らないメンバ関数へのポインタの場合
first_argument_type (C++17で非推奨) T* pm が1つの引数を取るメンバ関数へのポインタの場合
second_argument_type (C++17で非推奨) T1 pm が型 T1 の引数を1つ取るメンバ関数へのポインタの場合
(C++20まで)

メンバ関数

template < class ... Args >

/* 下記参照 */ operator ( ) ( Args && ... args ) /* cvref修飾子 */

noexcept ( /* 下記参照 */ ) ;
(C++20以降constexpr)

fn ( args ) INVOKE ( pmd, args ) と等価である。ここで pmd fn が保持する Callable オブジェクトであり、型 M T::* を持ち、 pm で直接非リスト初期化される。

したがって、 operator ( ) の戻り値の型は std:: result_of < decltype ( pm ) ( Args && ... ) > :: type または等価的に std:: invoke_result_t < decltype ( pm ) , Args && ... > であり、 noexcept 指定子の値は std:: is_nothrow_invocable_v < decltype ( pm ) , Args && ... > ) に等しい (C++17以降)

args の各引数は、 std:: forward < Args > ( args ) ... によって完全転送される。

std::mem_fn を使用してメンバ関数とメンバオブジェクトを格納および実行する:

#include <functional>
#include <iostream>
#include <memory>
struct Foo
{
    void display_greeting()
    {
        std::cout << "Hello, world.\n";
    }
    void display_number(int i)
    {
        std::cout << "number: " << i << '\n';
    }
    int add_xy(int x, int y)
    {
        return data + x + y;
    }
    template<typename... Args> int add_many(Args... args)
    {
        return data + (args + ...);
    }
    auto add_them(auto... args) // C++20 required
    {
        return data + (args + ...);
    }
    int data = 7;
};
int main()
{
    auto f = Foo{};
    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';
    auto add_xy = std::mem_fn(&Foo::add_xy);
    std::cout << "add_xy: " << add_xy(f, 1, 2) << '\n';
    auto u = std::make_unique<Foo>();
    std::cout << "access_data(u): " << access_data(u) << '\n';
    std::cout << "add_xy(u, 1, 2): " << add_xy(u, 1, 2) << '\n';
    auto add_many = std::mem_fn(&Foo::add_many<short, int, long>);
    std::cout << "add_many(u, ...): " << add_many(u, 1, 2, 3) << '\n';
    auto add_them = std::mem_fn(&Foo::add_them<short, int, float, double>);
    std::cout << "add_them(u, ...): " << add_them(u, 5, 7, 10.0f, 13.0) << '\n';
}

出力:

Hello, world.
number: 42
data: 7
add_xy: 10
access_data(u): 7
add_xy(u, 1, 2): 10
add_many(u, ...): 13
add_them(u, ...): 42

欠陥報告

以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。

DR 適用対象 公開時の動作 正しい動作
LWG 2048 C++11 不要なオーバーロードが提供されていた 削除
LWG 2489 C++11 noexcept 必須ではなかった 必須

関連項目

(C++11)
任意のコピー構築可能な呼び出し可能オブジェクトのコピー可能ラッパー
(クラステンプレート)
指定された呼び出しシグネチャで修飾子をサポートする任意の呼び出し可能オブジェクトのムーブ専用ラッパー
(クラステンプレート)
(C++11)
関数オブジェクトに1つ以上の引数をバインドする
(関数テンプレート)