Поделиться через


Класс function

Программа-оболочка для вызываемого объекта.

Синтаксис

template <class Fty>
class function  // Fty of type Ret(T1, T2, ..., TN)
    : public unary_function<T1, Ret>       // when Fty is Ret(T1)
    : public binary_function<T1, T2, Ret>  // when Fty is Ret(T1, T2)
{
public:
    typedef Ret result_type;

    function();
    function(nullptr_t);
    function(const function& right);
    template <class Fty2>
        function(Fty2 fn);
    template <class Fty2, class Alloc>
        function(reference_wrapper<Fty2>, const Alloc& Ax);

    template <class Fty2, class Alloc>
        void assign(Fty2, const Alloc& Ax);
    template <class Fty2, class Alloc>
        void assign(reference_wrapper<Fty2>, const Alloc& Ax);
    function& operator=(nullptr_t);
    function& operator=(const function&);
    template <class Fty2>
        function& operator=(Fty2);
    template <class Fty2>
        function& operator=(reference_wrapper<Fty2>);

    void swap(function&);
    explicit operator bool() const;

    result_type operator()(T1, T2, ....., TN) const;
    const std::type_info& target_type() const;
    template <class Fty2>
        Fty2 *target();

    template <class Fty2>
        const Fty2 *target() const;

    template <class Fty2>
        void operator==(const Fty2&) const = delete;
    template <class Fty2>
        void operator!=(const Fty2&) const = delete;
};

Параметры

Fty
Тип функции для заключения в оболочку.

Топор
Функция распределителя.

Замечания

Шаблон класса — это оболочка вызова, сигнатурой вызова которой является Ret(T1, T2, ..., TN). Он используется для заключения различных вызываемых объектов в единую оболочку.

Некоторые функции-члены принимают операнд с именем нужного целевого объекта. Такой операнд можно задать несколькими способами:

fn: вызываемый объект fn; после вызова function объекта содержит копию fn

fnref: вызываемый объект с fnref.get()именем; после вызова function объекта содержит ссылку на fnref.get()

right: вызываемый объект, если он есть, удерживаемый function объектом right

npc: указатель null; После вызова function объекта пусто

Во всех случаях INVOKE(f, t1, t2, ..., tN), где f является вызываемый объект и t1, t2, ..., tN являются lvalues типов T1, T2, ..., TN соответственно, должны быть хорошо сформированы и, если Ret не является пустотой, преобразуемой в Ret.

function Пустой объект не содержит вызываемый объект или ссылку на вызываемый объект.

Участники

Конструкторы

Имя Описание
function Создает оболочку, которая является пустой или содержит вызываемый объект произвольного типа с фиксированной сигнатурой.

Определения типов

Имя Описание
result_type Возвращаемый тип хранимого вызываемого объекта.

Функции

Имя Описание
assign Присваивает вызываемый объект данному объекту функции.
swap Меняет местами два вызываемых объекта.
целевой объект Проверяет, является ли вызываемый объект вызываемым, как указано.
target_type Возвращает сведения о типе в вызываемый объект.

Операторы

Имя Описание
оператор не указан Проверяет, существует ли вызываемый объект.
operator() Вызывает вызываемый объект.
operator= Заменяет хранимый вызываемый объект.

назначить

Присваивает вызываемый объект данному объекту функции.

template <class Fx, class Alloc>
    void assign(
        Fx _Func,
        const Alloc& Ax);

template <class Fx, class Alloc>
    void assign(
        reference_wrapper<Fx> _Fnref,
        const Alloc& Ax);

Параметры

_Func
Вызываемый объект.

_Fnref
Оболочка ссылки, которая содержит вызываемый объект.

Топор
Объект распределителя.

Замечания

Каждая функция-член заменяет callable object, который содержится в *this, на вызываемый объект, переданный как operand. Оба выделяют хранилище с помощью объекта Ax распределителя.

function

Создает оболочку, которая является пустой или содержит вызываемый объект произвольного типа с фиксированной сигнатурой.

function();
function(nullptr_t npc);
function(const function& right);
template <class Fx>
    function(Fx _Func);
template <class Fx>
    function(reference_wrapper<Fx> _Fnref);
template <class Fx, class Alloc>
    function(
        Fx _Func,
        const Alloc& Ax);

template <class Fx, class Alloc>
    function(
        reference_wrapper<Fx> _Fnref,
        const Alloc& Ax);

Параметры

right
Объект функции для копирования.

Fx
Тип вызываемого объекта.

_Func
Вызываемый объект, для которого создается оболочка.

Alloc
Тип распределителя.

Топор
Распределитель.

_Fnref
Ссылка на вызываемый объект для упаковки.

Замечания

Первые два конструктора создают пустой объект function. Следующие три конструктора создают объект function, который содержит вызываемый объект, переданный как операнд. Последние два конструктора выделяют память с объектом распределителя Ax.

Пример

// std__functional__function_function.cpp
// compile with: /EHsc
#include <functional>
#include <iostream>
#include <vector>

int square(int val)
{
    return val * val;
}

class multiply_by
{
public:
    explicit multiply_by(const int n) : m_n(n) { }

    int operator()(const int x) const
    {
        return m_n * x;
    }

private:
    int m_n;
};

int main()
{
    typedef std::vector< std::function<int (int)> > vf_t;

    vf_t v;
    v.push_back(square);
    v.push_back(std::negate<int>());
    v.push_back(multiply_by(3));

    for (vf_t::const_iterator i = v.begin(); i != v.end(); ++i)
    {
        std::cout << (*i)(10) << std::endl;
    }

    std::function<int (int)> f = v[0];
    std::function<int (int)> g;

    if (f) {
        std::cout << "f is non-empty (correct)." << std::endl;
    } else {
        std::cout << "f is empty (can't happen)." << std::endl;
    }

    if (g) {
        std::cout << "g is non-empty (can't happen)." << std::endl;
    } else {
        std::cout << "g is empty (correct)." << std::endl;
    }

    return 0;
}
100
-10
30
f is non-empty (correct).
g is empty (correct).

оператор не указан

Проверяет, существует ли вызываемый объект.

operator unspecified();

Замечания

Оператор возвращает значение, которое преобразуется в bool значение true, только если объект не пуст. Его можно использовать, чтобы проверить, является ли объект пустым.

Пример

// std__functional__function_operator_bool.cpp
// compile with: /EHsc
#include <functional>
#include <iostream>

int neg(int val)
    {
    return (-val);
    }

int main()
    {
    std::function<int (int)> fn0;
    std::cout << std::boolalpha << "not empty == " << (bool)fn0 << std::endl;

    std::function<int (int)> fn1(neg);
    std::cout << std::boolalpha << "not empty == " << (bool)fn1 << std::endl;

    return (0);
    }
not empty == false
not empty == true

operator()

Вызывает вызываемый объект.

result_type operator()(
    T1 t1,
    T2 t2, ...,
    TN tN);

Параметры

TN
Тип N-го аргумента вызова.

tN
N-й аргумент вызова.

Замечания

Функция-член возвращает INVOKE(fn, t1, t2, ..., tN, Ret), где fn — целевой объект, хранящийся в *this. Его можно использовать для вызова вызываемого объекта в оболочке.

Пример

// std__functional__function_operator_call.cpp
// compile with: /EHsc
#include <functional>
#include <iostream>

int neg(int val)
    {
    return (-val);
    }

int main()
    {
    std::function<int (int)> fn1(neg);
    std::cout << std::boolalpha << "empty == " << !fn1 << std::endl;
    std::cout << "val == " << fn1(3) << std::endl;

    return (0);
    }
empty == false
val == -3

operator=

Заменяет хранимый вызываемый объект.

function& operator=(null_ptr_type npc);
function& operator=(const function& right);
template <class Fty>
    function& operator=(Fty fn);
template <class Fty>
    function& operator=(reference_wrapper<Fty> fnref);

Параметры

npc
Константа указателя null.

right
Объект функции для копирования.

fn
Вызываемый объект, для которого создается оболочка.

fnref
Ссылка на вызываемый объект для упаковки.

Замечания

Каждый оператор заменяет вызываемый объект, который содержится в *this, на вызываемый объект, переданный как операнд.

Пример

// std__functional__function_operator_as.cpp
// compile with: /EHsc
#include <functional>
#include <iostream>

int neg(int val)
    {
    return (-val);
    }

int main()
    {
    std::function<int (int)> fn0(neg);
    std::cout << std::boolalpha << "empty == " << !fn0 << std::endl;
    std::cout << "val == " << fn0(3) << std::endl;

    std::function<int (int)> fn1;
    fn1 = 0;
    std::cout << std::boolalpha << "empty == " << !fn1 << std::endl;

    fn1 = neg;
    std::cout << std::boolalpha << "empty == " << !fn1 << std::endl;
    std::cout << "val == " << fn1(3) << std::endl;

    fn1 = fn0;
    std::cout << std::boolalpha << "empty == " << !fn1 << std::endl;
    std::cout << "val == " << fn1(3) << std::endl;

    fn1 = std::cref(fn1);
    std::cout << std::boolalpha << "empty == " << !fn1 << std::endl;
    std::cout << "val == " << fn1(3) << std::endl;

    return (0);
    }
empty == false
val == -3
empty == true
empty == false
val == -3
empty == false
val == -3
empty == false
val == -3

result_type

Возвращаемый тип хранимого вызываемого объекта.

typedef Ret result_type;

Замечания

typedef — синоним типа Ret в сигнатуре вызова шаблона. Его можно использовать, чтобы определить возвращаемый тип упакованного вызываемого объекта.

Пример

// std__functional__function_result_type.cpp
// compile with: /EHsc
#include <functional>
#include <iostream>

int neg(int val)
    {
    return (-val);
    }

int main()
    {
    std::function<int (int)> fn1(neg);
    std::cout << std::boolalpha << "empty == " << !fn1 << std::endl;

    std::function<int (int)>::result_type val = fn1(3);
    std::cout << "val == " << val << std::endl;

    return (0);
    }
empty == false
val == -3

swap

Меняет местами два вызываемых объекта.

void swap(function& right);

Параметры

right
Объект функции для обмена.

Замечания

Функция-член переключает целевые объекты между *this и справа. Она делает это в константном времени и не создает исключений.

Пример

// std__functional__function_swap.cpp
// compile with: /EHsc
#include <functional>
#include <iostream>

int neg(int val)
    {
    return (-val);
    }

int main()
    {
    std::function<int (int)> fn0(neg);
    std::cout << std::boolalpha << "empty == " << !fn0 << std::endl;
    std::cout << "val == " << fn0(3) << std::endl;

    std::function<int (int)> fn1;
    std::cout << std::boolalpha << "empty == " << !fn1 << std::endl;
    std::cout << std::endl;

    fn0.swap(fn1);
    std::cout << std::boolalpha << "empty == " << !fn0 << std::endl;
    std::cout << std::boolalpha << "empty == " << !fn1 << std::endl;
    std::cout << "val == " << fn1(3) << std::endl;

    return (0);
    }
empty == false
val == -3
empty == true

empty == true
empty == false
val == -3

целевой объект

Проверяет, является ли вызываемый объект вызываемым, как указано.

template <class Fty2>
    Fty2 *target();
template <class Fty2>
    const Fty2 *target() const;

Параметры

Fty2
Тип целевого вызываемого объекта для проверки.

Замечания

Тип Fty2 должен вызываться для типов аргументов T1, T2, ..., TN и возвращаемого типа Ret. Если target_type() == typeid(Fty2), шаблон функций-членов возвращает адрес целевого объекта; в противном случае возвращается 0.

Тип Fty2 вызывается для типов аргументов и возвращаемого типаRet, если для lvalues fn, t1, t2, ..., tN типов T1, T2, ..., TN Fty2, T1, T2, ..., TN, соответственно, INVOKE(fn, t1, t2, ..., tN) является хорошо сформированным и, если Ret не voidявляется, преобразуется в Ret.

Пример

// std__functional__function_target.cpp
// compile with: /EHsc
#include <functional>
#include <iostream>

int neg(int val)
    {
    return (-val);
    }

int main()
    {
    typedef int (*Myfun)(int);
    std::function<int (int)> fn0(neg);
    std::cout << std::boolalpha << "empty == " << !fn0 << std::endl;
    std::cout << "no target == " << (fn0.target<Myfun>() == 0) << std::endl;

    Myfun *fptr = fn0.target<Myfun>();
    std::cout << "val == " << (*fptr)(3) << std::endl;

    std::function<int (int)> fn1;
    std::cout << std::boolalpha << "empty == " << !fn1 << std::endl;
    std::cout << "no target == " << (fn1.target<Myfun>() == 0) << std::endl;

    return (0);
    }
empty == false
no target == false
val == -3
empty == true
no target == true

target_type

Возвращает сведения о типе в вызываемый объект.

const std::type_info& target_type() const;

Замечания

Функция-член возвращает typeid(void), если значение *this пустое, в противном случае возвращает typeid(T), где T — тип целевого объекта.

Пример

// std__functional__function_target_type.cpp
// compile with: /EHsc
#include <functional>
#include <iostream>

int neg(int val)
    {
    return (-val);
    }

int main()
    {
    std::function<int (int)> fn0(neg);
    std::cout << std::boolalpha << "empty == " << !fn0 << std::endl;
    std::cout << "type == " << fn0.target_type().name() << std::endl;

    std::function<int (int)> fn1;
    std::cout << std::boolalpha << "empty == " << !fn1 << std::endl;
    std::cout << "type == " << fn1.target_type().name() << std::endl;

    return (0);
    }
empty == false
type == int (__cdecl*)(int)
empty == true
type == void