Function Adapters and Binders - C++11, 4 of n

A function adapter is a function object that enables the composition of function objects with each other, with certain values, or with special functions.
Function adaptors provided by C++11.

1) The bind() Adapter - binds parameters for callable objects

using std;
using std::placeholder

// Normal binding
auto plus10 = bind(plus<int>(), _1, 10);
// internally calls plus<> (i.e., operator +), with a placeholder _1
// as first parameter/operand and 10 as second parameter/operand
cout << "+10: " << plus10(7) << endl; 

auto plus10times2 = bind(multiplies<int>(), bind(plus<int>(), _1, 10), 2);
cout << "+10 *2: " << plus10times2(7) << endl;

auto pow3 = bind(multiplies<int>(), bind(multiplies<int>(), _1, _1), _1);
cout << "x*x*x: " << pow3(7) << endl;

auto inversDivide = bind(divides<double>(), _2, _1);
cout << "invdiv: " << inversDivide(49,7) << endl;

// Call global function
char myToupper (char c)
{
    std::locale loc;
    return std::use_facet<std::ctype<char> >(loc).toupper(c);
}

bind(equal_to<char>(),  bind(myToupper,_1), bind(myToupper,_2)));
// Create func object: myToupper(param1)==myToupper(param2)

// Note that bind() internally copies passed arguments. To let the function object use a reference
// to a passed argument, use ref() or cref()

void incr (int& i)
{
    ++i;
}
int i=0;
bind(incr,i)(); // increments a copy of i, no effect for i
bind(incr,ref(i))(); // increments i

// Calling Member Functions
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;
    }
};

vector<Person> coll = { Person("Tick"), Person("Trick"), Person("Track") };
for_each (coll.begin(), coll.end(), bind(&Person::print,_1));
for_each (coll.begin(), coll.end(), bind(&Person::print2,_1,"Person: "));

bind(&Person::print,_1)
// defines a function object that calls param1.print() for a passed Person.
// That is, because the first argument is a member function, the next argument
// defines the object for which this member function gets called

bind(&Person::print2,_1,"Person: ")
// defines a function object that calls param1.print2("Person: ") for any passed Person

// bind pointers
vector<Person*> cp;
...
for_each (cp.begin(), cp.end(), bind(&Person::print, _1));

vector<shared_ptr<Person>> sp;
...
for_each (sp.begin(), sp.end(), bind(&Person::print, _1));

2) The mem_fn() Adapter
simply calls an initialized member function for a passed argument while additional
arguments are passed as parameters to the member function:

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.print2("Person: ")

// Binding to Data Members
map<string,int> coll;
int sum = accumulate (coll.begin(), coll.end(),
                                          0,
                                          bind(plus<int>(), _1, bind(&map<string,int>::value_type::second, _2)));
auto f1 = bind(&map<string,int>::value_type::second, _2);
auto f2 = bind(plus<int>(), _1, f1);
f2(value, *iter) => plus<int>(value, f1(*iter))
f1(*iter) => f1(pair<const string, int> p) => p.second 
(second is the data member of pair class, in order to access this data member, we need bind a pair instance)

WHY SO COMPLICATED ?
We have more powerful weapon, lambdas
!!!

// accumulate implementation reference
template<class InputIt, class T, class BinaryOperation>
T accumulate(InputIt first, InputIt last, T value,  BinaryOperation op)
{
    for (; first != last; ++first) {
        value = op(value, *first);
    }
    return value;
}

3) not1() and not2 are almost deprecated since C++11, and so others.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值