名前空間
変種
操作

std::mem_fn

From cppreference.com
< cpp‎ | utility‎ | functional
 
 
ユーティリティライブラリ
言語サポート
型のサポート (基本型、RTTI)
ライブラリ機能検査マクロ (C++20)
プログラムユーティリティ
可変引数関数
コルーチンサポート (C++20)
契約サポート (C++26)
三方比較
(C++20)
(C++20)(C++20)(C++20)  
(C++20)(C++20)(C++20)

汎用ユーティリティ
関係演算子 (C++20で非推奨)
 
関数オブジェクト
関数の呼び出し
(C++17)(C++23)
恒等関数オブジェクト
(C++20)
透過的な演算子ラッパー
(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)

古いバインダとアダプタ
(C++17まで*)
(C++17まで*)
(C++17まで*)
(C++17まで*)  
(C++17まで*)
(C++17*まで)(C++17*まで)(C++17*まで)(C++17*まで)
(C++20まで*)
(C++20まで*)
(C++17*まで)(C++17*まで)
(C++17*まで)(C++17*まで)

(C++17まで*)
(C++17*まで)(C++17*まで)(C++17*まで)(C++17*まで)
(C++20まで*)
(C++20まで*)
 
ヘッダ <functional> で定義
template< class M, class T >
/* 未指定 */ mem_fn( M T::* pm ) noexcept;
(C++11以降)
(C++20 以降 constexpr)

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

目次

[編集] パラメーター

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

[編集] 戻り値

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

std::mem_fn 戻り値の型

メンバ型

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

メンバー関数

template< class... Args >

/* 以下を参照 */ operator()(Args&&... args) /* cvref-qualifiers */

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

fn(args)は、INVOKE(pmd, args)と同等です。pmdfnが保持する呼び出し可能オブジェクトであり、型は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つ以上の引数を関数オブジェクトに束縛する
(関数テンプレート) [編集]
English 日本語 中文(简体) 中文(繁體)