C++函数对象-引用包装器-创建具有从其实参推导的类型的 std::reference_wrapper(std::ref, std::cref)

任何定义了函数调用操作符的对象都是函数对象。C++ 支持创建、操作新的函数对象,同时也提供了许多内置的函数对象。

引用包装器


引用包装器允许存储引用到可复制的函数对象中:

创建具有从其实参推导的类型的 std::reference_wrapper

std::ref, 
std::cref

template< class T >
std::reference_wrapper ref(T& t) noexcept;

(1) (C++11 起)

template< class T >
std::reference_wrapper ref( std::reference_wrapper t ) noexcept;

(2) (C++11 起)

template
void ref(const T&&) = delete;

(3) (C++11 起)

template< class T >
std::reference_wrapper cref( const T& t ) noexcept;

(4) (C++11 起)

template< class T >
std::reference_wrapper cref( std::reference_wrapper t ) noexcept;

(5) (C++11 起)

template
void cref(const T&&) = delete;

(6) (C++11 起)

函数模板 refcref 是生成 std::reference_wrapper 类型对象的帮助函数,它们用模板实参推导确定结果的模板实参。

T 可为不完整类型。

(C++20 起)

参数

t - 需要被包装的到对象的左值引用,或 std::reference_wrapper 的实例

返回值

1) std::reference_wrapper(t)

2) ref(t.get())

4) std::reference_wrapper(t)

5) cref(t.get())

3,6) 右值引用包装器被删除。

调用示例

#include 
#include 
#include 
#include 
#include 
#include 
#include 

struct Cell
{
    int x;
    int y;

    Cell() = default;
    Cell(int a, int b): x(a), y(b) {}
    Cell(const Cell &cell)
    {
        x = cell.x;
        y = cell.y;
    }

    bool operator <(const Cell &cell) const
    {
        if (x == cell.x)
        {
            return y < cell.y;
        }
        else
        {
            return x < cell.x;
        }
    }

    Cell &operator+(const Cell &cell)
    {
        x += cell.x;
        y += cell.y;
        return *this;
    }

    Cell &operator+=(const Cell &cell)
    {
        x += cell.x;
        y += cell.y;
        return *this;
    }

    Cell &operator*=(int n)
    {
        x *= n;
        y *= n;
        return *this;
    }

    Cell &operator++()
    {
        x += 1;
        y += 1;
        return *this;
    }
};

std::ostream &operator<<(std::ostream &os, const Cell &cell)
{
    os << "{" << cell.x << "," << cell.y << "}";
    return os;
}

void Function1(Cell &cell1, Cell &cell2, const Cell &cell3)
{
    std::cout << __FUNCTION__ << "    "
              << cell1 << ' ' << cell2 << ' ' << cell3 << std::endl;
    cell1 += cell1; // 增加存储于函数对象的 cell1 副本
    cell2 += cell2; //增加 main() 的 n2
    //cell3 += cell3;// 编译错误
}

int main()
{
    Cell cell1 = {101, 101};
    Cell cell2 = {102, 102};
    Cell cell3 = {103, 103};

    std::function bound_f = std::bind(Function1, cell1, std::ref(cell2), std::cref(cell3));
    cell1 = {101, 101};
    cell2 = {102, 102};
    cell3 = {103, 103};
    std::cout << "Before function: " << std::endl;
    std::cout << cell1 << ' ' << cell2 << ' ' << cell3 << std::endl;
    bound_f();
    std::cout << "After function: " << std::endl;
    std::cout << cell1 << ' ' << cell2 << ' ' << cell3 << std::endl;

    return 0;
}

输出

Before function:
{101,101} {102,102} {103,103}
Function1    {101,101} {102,102} {103,103}
After function:
{101,101} {204,204} {103,103}

你可能感兴趣的:(#,引用包装器,c++,标准库模板,STL,函数对象,函数包装器,ref,cref)