Spec-Zone.ru › C++

std::mem_fn

Определено в заголовке <functional>
template< class M, class T >
/* unspecified */ mem_fn( M T::* pm ) noexcept;
(с C++11)
(до C++20)
template< class M, class T >
constexpr /* unspecified */ mem_fn( M T::* pm ) noexcept;
(с C++20)

Шаблон функции std::mem_fn генерирует объекты-обертки для указателей на члены, которые могут хранить, копировать и вызывать указатель на член. При вызове std::mem_fn могут использоваться как ссылки, так и указатели (включая умные указатели) на объект.

Параметры

pm - указатель на член, который будет обернут

Возвращаемое значение

std::mem_fn возвращает оболочку вызова fn неопределённого типа, имеющую следующие члены:

std::mem_fn тип возврата

Типы членов

тип определение
result_type(устарело в C++17) тип возврата pm если pm — указатель на член-функцию, не определено для указателя на член-объект
argument_type(устарело в C++17) T*, возможно с квалификаторами cv, если pm — указатель на член-функцию без аргументов
first_argument_type(устарело в C++17) T* если pm — указатель на член-функцию с одним аргументом
second_argument_type(устарело в C++17) T1 если pm — указатель на член-функцию с одним аргументом типа T1
(до C++20)

Член-функция

template< class... Args >
/* see below */ operator()(Args&&... args) /* cvref-qualifiers */
    noexcept(/* see below */);
(до C++20)
template< class... Args >
constexpr /* see below */ operator()(Args&&... args) /* cvref-qualifiers */
    noexcept(/* see below */);
(с C++20)

Выражение fn(args) эквивалентно INVOKE(pmd, args), где pmd — объект Callable, хранимый в fn, его тип M T::*, и он инициализируется напрямую без списка pm.

Таким образом, тип возврата оператора() — 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 не требуется требуется

См. также

function
(C++11)
оборачивает вызываемый объект любого копируемого типа со специфицированной сигнатурой вызова функции
(шаблон класса)
move_only_function
(C++23)
оборачивает вызываемый объект любого типа со специфицированной сигнатурой вызова функции
(шаблон класса)
bind
(C++11)
связывает один или несколько аргументов с объектом функции
(шаблон функции)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/utility/functional/mem_fn

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API