任何定义了函数调用操作符的对象都是函数对象。C++ 支持创建、操作新的函数对象,同时也提供了许多内置的函数对象。
引用包装器允许存储引用到可复制的函数对象中:
std::reference_wrapper
template< class T > |
(C++11 起) |
std::reference_wrapper
是包装引用于可复制、可赋值对象的类模板。它常用作将容器存储入无法正常保有引用的标准容器(类似 std::vector )的机制。
std::reference_wrapper::reference_wrapper
template< class U > |
(1) | |
reference_wrapper( const reference_wrapper& other ) noexcept; |
(2) |
构造新的 reference_wrapper 。
1) 如同用 T& t = std::forward(x); 转换 x
为 T&
,然后存储到 t
的引用。此重载仅若 typename std::decay::type 与 reference_wrapper
不是同一类型且表达式 FUN(std::declval()) 为良式才参与重载决议,其中 FUN
指名虚构函数集
void FUN(T&) noexcept; void FUN(T&&) = delete;
2) 复制构造函数。存储到 other.get()
的引用。
x | - | 要包装的对象 |
other | - | 另一 reference_wrapper |
1)noexcept 规定:
noexcept(noexcept(FUN(std::declval())))
,其中 FUN
是以上描述中的虚构函数集。
#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*=(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;
}
int main()
{
Cell cell1 = {1024, 1024};
std::reference_wrapper reference_wrapper(cell1);
std::cout << "reference_wrapper: " << reference_wrapper << std::endl;
cell1 = {1025, 1025};
std::cout << "reference_wrapper: " << reference_wrapper << std::endl;
std::cout << "cell1: " << cell1 << std::endl;
return 0;
} |
reference_wrapper: {1024,1024}
reference_wrapper: {1025,1025}
cell1: {1025,1025}
std::reference_wrapper::operator=
reference_wrapper& operator=( const reference_wrapper |
(C++11 起) |
复制赋值运算符。丢弃当前引用,并存储到 other.get() 的引用。
other | - | 要复制的 reference_wrapper |
*this
#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*=(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;
}
int main()
{
Cell cell1 = {1024, 1024};
std::cout << "cell1: " << cell1 << std::endl;
std::reference_wrapper reference_wrapper1(cell1);
std::reference_wrapper reference_wrapper2 = reference_wrapper1;
std::cout << "reference_wrapper1: " << reference_wrapper1 << std::endl;
std::cout << "reference_wrapper2: " << reference_wrapper2 << std::endl;
cell1 = {1025, 1025};
std::cout << "cell1: " << cell1 << std::endl;
std::cout << "reference_wrapper1: " << reference_wrapper1 << std::endl;
std::cout << "reference_wrapper2: " << reference_wrapper2 << std::endl;
return 0;
} | |
cell1: {1024,1024}
reference_wrapper1: {1024,1024}
reference_wrapper2: {1024,1024}
cell1: {1025,1025}
reference_wrapper1: {1025,1025}
reference_wrapper2: {1025,1025}
std::reference_wrapper::get,
std::reference_wrapper::operator T&
operator T& () const noexcept; |
(C++11 起) | |
T& get() const noexcept; |
(C++11 起) |
返回存储的引用。
(无)
存储的引用。
#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*=(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;
}
int main()
{
Cell cell1 = {1024, 1024};
std::cout << "cell1: " << cell1 << std::endl;
std::reference_wrapper reference_wrapper1(cell1);
std::reference_wrapper reference_wrapper2 = reference_wrapper1;
std::cout << "reference_wrapper1: " << reference_wrapper1.get() << std::endl;
std::cout << "reference_wrapper2: " << reference_wrapper2.get() << std::endl;
cell1 = {1025, 1025};
std::cout << "cell1: " << cell1 << std::endl;
std::cout << "reference_wrapper1: " << reference_wrapper1 << std::endl;
std::cout << "reference_wrapper2: " << reference_wrapper2 << std::endl;
return 0;
} | |
cell1: {1024,1024}
reference_wrapper1: {1024,1024}
reference_wrapper2: {1024,1024}
cell1: {1025,1025}
reference_wrapper1: {1025,1025}
reference_wrapper2: {1025,1025}
std::reference_wrapper::operator()
template< class... ArgTypes > typename std::result_of |
(C++11 起) (C++17 前) |
|
template< class... ArgTypes > std::invoke_result_t |
(C++17 起) |
调用存储其引用的可调用 (Callable) 对象。仅若存储的引用指向可调用 (Callable) 对象,此函数才可用。
T
必须是完整类型。
args | - | 传递给被调用函数的参数 |
被调用函数的返回值。
(无)
#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*=(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()
{
std::cout << __FUNCTION__ << " " << Cell{1024, 1024} << std::endl;
}
void Function2(Cell cell1)
{
std::cout << __FUNCTION__ << " " << cell1 + Cell{1024, 1024} << std::endl;
}
int main()
{
std::reference_wrapper reference_wrapper1 = std::ref(Function1);
reference_wrapper1();
auto function2 = std::bind(Function2, std::placeholders::_1);
auto reference_wrapper2 = std::ref(function2);
reference_wrapper2(Cell{1024, 1024});
auto function3 = []()
{
std::cout << "lambda function called" << std::endl;
};
auto reference_wrapper3 = std::ref(function3);
reference_wrapper3();
return 0;
}
Function1 {1024,1024}
Function2 {2048,2048}
lambda function called
std::reference_wrapper
的推导指引 template |
(C++17 起) |
为 std::reference_wrapper 提供推导指引以支持单独类模板形参的推导。