任何定义了函数调用操作符的对象都是函数对象。C++ 支持创建、操作新的函数对象,同时也提供了许多内置的函数对象。
std::bind_front 与 std::bind 提供部分函数应用的支持,即绑定参数到函数以创建新函数。
std::is_placeholder
template< class T > | (C++11 起) |
若 T
是标准占位符( _1 、 _2 、 _3 ……)的类型,则此模板分别派生自 std::integral_constant<int,1> 、 std::integral_constant<int,2> 、 std::integral_constant<int,3> 。
若 T
不是标准占位符类型,则此模板派生自 std::integral_constant<int,0> 。
可以为任何用户定义 T
类型特化模板:特化必须满足一元类型特征 (UnaryTypeTrait) ,拥有 std::integral_constant<int, N> 而 N > 0 指示 T
应被处理成第 N 个占位符类型的基特征 (BaseCharacteristic) 。
std::bind 用 std::is_placeholder
检测未绑定参数的占位符。
template< class T > |
?
value [静态] | 占位符值,或对于非占位符类型为 0 (公开静态成员常量) |
operator int | 转换对象为 int ,返回 value (公开成员函数) |
operator() (C++14) | 返回 value (公开成员函数) |
类型 | 定义 |
value_type | int |
type | std::integral_constant<int, value> |
#include <iostream>
#include <type_traits>
#include <functional>
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;
}
};
std::ostream &operator<<(std::ostream &os, const Cell &cell)
{
os << "{" << cell.x << "," << cell.y << "}";
return os;
}
struct MyBind1
{
};
struct MyBind2
{
};
namespace std
{
//第二个参数
template<>
struct is_placeholder<MyBind1> : public integral_constant<int, 1> {};
//第二个参数
template<>
struct is_placeholder<MyBind2> : public integral_constant<int, 2> {};
}
Cell Function1(Cell cell1, Cell cell2)
{
return cell1 + cell2;
}
int main()
{
std::cout << "Standard placeholder _1 is for the argument number: "
<< std::is_placeholder<decltype(std::placeholders::_1)>::value
<< std::endl;
std::cout << "Standard placeholder _2 is for the argument number: "
<< std::is_placeholder<decltype(std::placeholders::_2)>::value
<< std::endl;
std::cout << "Standard placeholder _5 is for the argument number: "
<< std::is_placeholder<decltype(std::placeholders::_5)>::value
<< std::endl;
std::cout << "Standard placeholder _16 is for the argument number: "
<< std::is_placeholder<decltype(std::placeholders::_16)>::value
<< std::endl;
std::cout << "Standard placeholder _17 is for the argument number: "
<< std::is_placeholder<decltype(std::placeholders::_17)>::value
<< std::endl;
// 取第一个参数
MyBind1 myBind1;
auto function1 = std::bind(Function1, myBind1, Cell{108, 108});
std::cout << "Adding Cell{108, 108} to Cell{106, 106} selected with a custom placeholder gives "
<< function1(Cell{106, 106}, Cell{107, 107}) << std::endl;
// 取第二个参数
MyBind2 myBind2;
auto function2 = std::bind(Function1, myBind2, Cell{108, 108});
std::cout << "Adding Cell{108, 108} to Cell{107, 107} selected with a custom placeholder gives "
<< function2(Cell{106, 106}, Cell{107, 107}) << std::endl;
return 0;
}
Standard placeholder _1 is for the argument number: 1
Standard placeholder _2 is for the argument number: 2
Standard placeholder _5 is for the argument number: 5
Standard placeholder _16 is for the argument number: 16
Standard placeholder _17 is for the argument number: 17
Adding Cell{108, 108} to Cell{106, 106} selected with a custom placeholder gives {214,214}
Adding Cell{108, 108} to Cell{107, 107} selected with a custom placeholder gives {215,215}