头文件<functional>
预定义的function object
对对象排序或比较时,默认以less<>为比较准则,因此默认的排序操作总是产生升序.
…
…
Function Adapter和Binder
所谓的Function adapter(函数适配器,函数改造器),指能够将不通的函数对象结合起来的东西,它自身也是一个函数对象.
C++11引入了更方便更弹性的adapter.下面是C++11开始,C++STL提供的函数适配器
其中最重要的adapter就是bind(),它允许:
1.让一个函数对象配接合成新的函数对象
2.调用全局函数
3.针对对象、对象指针、对象智能指针调用成员函数
下面是一个Binder的典型应用:
int main()
{
auto plus10 = bind(plus<int>(), placeholders::_1, 10);
cout << "+10: " << plus10(7) << endl;
auto plus10times2 = bind(multiplies<int>(), bind(plus<int>(), placeholders::_1, 10), 2);
cout << "+10 * 2: " << plus10times2(7) << endl;
auto pow3 = bind(multiplies<int>(), bind(multiplies<int>(), placeholders::_1, placeholders::_1), placeholders::_1);
cout << "x*x*x " << pow3(7) << endl;
auto inversdivide = bind(divides<double>(), placeholders::_2, placeholders::_1);
cout << "invdiv: " << inversdivide(49, 7) << endl;
}
其中placeholders_1、_2、…是预定义占位符,被定义于命名空间placeholders
使用using指示符,可以缩短整个语句:
using namespace std;
using namespace std::placeholders;
Bind(plus<int>(),_1,10)
也可以直接调用binder而不必先为它建立一个对应的函数对象,比如:
Cout << bind(plus<int>(),_1,10)(32) << endl;
调用全局函数:
using namespace std;
using namespace std::placeholders;
char myToupper(char c)
{
locale loc;
return use_facet<ctype<char>>(loc).toupper(c);
}
int main()
{
string s("Internationalization");
string sub("Nation");
string::iterator pos;
pos = search(s.begin(), s.end(), sub.begin(), sub.end(), bind(equal_to<char>(), bind(myToupper, _1), bind(myToupper, _2)));
if (pos != s.end())
{
cout << "\"" << sub << "\" is part of \"" << s << "\"" << endl;
}
}
调用成员函数:
class Person
{
private:
string name;
public:
Person(const string& n) :name(n) {}
void print()const
{
cout << name << endl;
}
void print2(const string& prefix)const
{
cout << prefix << name << endl;
}
};
int main()
{
vector<Person>coll{ Person("Tick"), Person("Trick"),Person{"Track"} };
for_each(coll.begin(), coll.end(), bind(&Person::print, _1));
cout << endl;
for_each(coll.begin(), coll.end(), bind(&Person::print2, _1, "Person: "));
cout << endl;
bind(&Person::print2, _1, "This is: ")(Person("nico"));
}
Mem_fn()adapter
若有额外实参被传给成员函数,mem_fn就拿其中第一实参作为调用者,其他实参当做成员函数的实参:
...
for_each(coll.begin(), coll.end(), mem_fn(&Person::print));
mem_fn(&Person::print)(n);//calls n.print()
mem_fn(&Person::print2)(n,"Person: ");//calls n.print()
...
绑定至数据成员
map<string, int>coll;
int sum = accumulate(coll.begin(), coll.end(), 0, bind(plus<int>(), _1, bind(&map<string, int>::value_type::second, _2)));
…
…
…
以Function Adapter搭配用户自定义的Function Object
你也可以把binder用在你自定义的函数对象身上,下面展示了一份函数对象的完整定义:
template<typename T1, typename T2>
struct fopow
{
T1 operator()(T1 base, T2 exp)const
{
return std::pow(base, exp);
}
};
int main()
{
vector<int>coll{ 1,2,3,4,5,6,7,8,9 };
transform(coll.begin(), coll.end(), ostream_iterator<float>(cout, " "), bind(fopow<float, int>(), 3, _1));
cout << endl;
transform(coll.begin(), coll.end(), ostream_iterator<float>(cout, " "), bind(fopow<float, int>(), _1, 3));
cout << endl;
}