任何定义了函数调用操作符的对象都是函数对象。C++ 支持创建、操作新的函数对象,同时也提供了许多内置的函数对象。
std::bind_front 与 std::bind 提供部分函数应用的支持,即绑定参数到函数以创建新函数。
std::placeholders::_1,
std::placeholders::_2,
...,
std::placeholders::_N
定义于头文件 |
||
/*see below*/ _1; /*see below*/ _2; |
std::placeholders 命名空间含有占位对象 [_1, . . . _N]
,其中 N
是实现定义的最大数字。
于 std::bind 表达式用作参数时,占位符对象被存储于生成的函数对象,而以未绑定参数调用函数对象时,每个占位符 _N
被对应的第 N 个未绑定参数替换。
每个占位符如同以 extern /*unspecified*/ _1; 声明。 |
(C++17 前) |
鼓励实现如同以 inline constexpr /*unspecified*/ _1; 声明占位符,尽管标准仍然允许以 extern /*unspecified*/ _1; 声明它们。 |
(C++17 起) |
占位符对象的类型可默认构造 (DefaultConstructible) 且可复制构造 (CopyConstructible) ,其默认复制/移动构造函数不抛异常,且对于任何占位符 _N
,类型 std::is_placeholder
namespace placeholders
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/* Define a large number of placeholders. There is no way to
* simplify this with variadic templates, because we're introducing
* unique names for each.
*/
extern const _Placeholder<1> _1;
extern const _Placeholder<2> _2;
extern const _Placeholder<3> _3;
extern const _Placeholder<4> _4;
extern const _Placeholder<5> _5;
extern const _Placeholder<6> _6;
extern const _Placeholder<7> _7;
extern const _Placeholder<8> _8;
extern const _Placeholder<9> _9;
extern const _Placeholder<10> _10;
extern const _Placeholder<11> _11;
extern const _Placeholder<12> _12;
extern const _Placeholder<13> _13;
extern const _Placeholder<14> _14;
extern const _Placeholder<15> _15;
extern const _Placeholder<16> _16;
extern const _Placeholder<17> _17;
extern const _Placeholder<18> _18;
extern const _Placeholder<19> _19;
extern const _Placeholder<20> _20;
extern const _Placeholder<21> _21;
extern const _Placeholder<22> _22;
extern const _Placeholder<23> _23;
extern const _Placeholder<24> _24;
extern const _Placeholder<25> _25;
extern const _Placeholder<26> _26;
extern const _Placeholder<27> _27;
extern const _Placeholder<28> _28;
extern const _Placeholder<29> _29;
_GLIBCXX_END_NAMESPACE_VERSION
}
#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;
}
};
namespace std
{
namespace placeholders
{
extern const _Placeholder<1024> _1024;
}
}
std::ostream &operator<<(std::ostream &os, const Cell &cell)
{
os << "{" << cell.x << "," << cell.y << "}";
return os;
}
void Function1(Cell cell1, Cell cell2, Cell cell3, const Cell& cell4, Cell cell5)
{
std::cout << cell1 << ' ' << cell2 << ' ' << cell3 << ' '
<< cell4 << ' ' << cell5 << std::endl;
}
int main()
{
std::cout << "Standard placeholder _1 is for the argument number: "
<< std::is_placeholder::value
<< std::endl;
std::cout << "Standard placeholder _2 is for the argument number: "
<< std::is_placeholder::value
<< std::endl;
std::cout << "Standard placeholder _4 is for the argument number: "
<< std::is_placeholder::value
<< std::endl;
std::cout << "Standard placeholder _5 is for the argument number: "
<< std::is_placeholder::value
<< std::endl;
std::cout << "Standard placeholder _8 is for the argument number: "
<< std::is_placeholder::value
<< std::endl;
std::cout << "Standard placeholder _16 is for the argument number: "
<< std::is_placeholder::value
<< std::endl;
std::cout << "Standard placeholder _17 is for the argument number: "
<< std::is_placeholder::value
<< std::endl;
std::cout << "Standard placeholder _18 is for the argument number: "
<< std::is_placeholder::value
<< std::endl;
std::cout << "Standard placeholder _20 is for the argument number: "
<< std::is_placeholder::value
<< std::endl;
std::cout << "Standard placeholder _24 is for the argument number: "
<< std::is_placeholder::value
<< std::endl;
std::cout << "Standard placeholder _28 is for the argument number: "
<< std::is_placeholder::value
<< std::endl;
std::cout << "Standard placeholder _29 is for the argument number: "
<< std::is_placeholder::value
<< std::endl;
std::cout << "Standard placeholder _1024 is for the argument number: "
<< std::is_placeholder::value
<< std::endl;
std::cout << std::endl;
// 演示参数重排序和按引用传递
Cell cell1 = {101, 101};
// ( _1 与 _2 来自 std::placeholders ,并表示将来会传递给 f1 的参数)
auto function1 = std::bind(Function1, std::placeholders::_2,
Cell{102, 102}, std::placeholders::_1, std::cref(cell1), cell1);
cell1 = {1024, 1024};
// Cell{103, 103} 为 _1 所绑定, Cell{104, 104} 为 _2 所绑定,不使用 Cell{105, 105}
// 进行到 Function1(Cell{104, 104}, Cell{102, 102}, Cell{103, 103}, cell1, Cell{101, 101}) 的调用
function1(Cell{103, 103}, Cell{104, 104}, Cell{105, 105});
return 0;
}
Standard placeholder _1 is for the argument number: 1
Standard placeholder _2 is for the argument number: 2
Standard placeholder _4 is for the argument number: 4
Standard placeholder _5 is for the argument number: 5
Standard placeholder _8 is for the argument number: 8
Standard placeholder _16 is for the argument number: 16
Standard placeholder _17 is for the argument number: 17
Standard placeholder _18 is for the argument number: 18
Standard placeholder _20 is for the argument number: 20
Standard placeholder _24 is for the argument number: 24
Standard placeholder _28 is for the argument number: 28
Standard placeholder _29 is for the argument number: 29
Standard placeholder _1024 is for the argument number: 1024
{104,104} {102,102} {103,103} {1024,1024} {101,101}