小十四

下标运算符要有const与非const重载两种版本。

struct absInt {
    int operator()(int val) const {
        return val < 0 ? -val : val;
    }
};
//函数对象,如同一个lambda

int main() {
    int i = -42;
    absInt absObj;           // object that has a function-call operator
    unsigned ui = absObj(i); // passes i to absObj.operator()
    cout << i << " " << ui << endl;

    // store collection of positive and negative integers in vi
    vector<int> vi;
    while (cin >> i)
        vi.push_back(i);

    // call absInt to store the absolute value of those ints in vu
    vector<unsigned> vu;
    transform(vi.begin(), vi.end(), back_inserter(vu), absInt());

    // print contents of vu using a lambda
    for_each(vu.begin(), vu.end(), [](unsigned i) { cout << i << " "; });
    cout << endl;

    vector<unsigned> vu2;
    // similar transformation but using a lambda
    transform(vi.begin(), vi.end(), back_inserter(vu2),
              [](int i) { return i < 0 ? -i : i; });
    if (vu == vu2)
        cout << "as expected" << endl;
    else {
        cout << "something's wrong, vectors differ" << endl;
        for_each(vu.begin(), vu.end(), [](unsigned i) { cout << i << " "; });
    }
    cout << endl;

    return 0;
}

lambda有捕获列表,对于函数对象来讲,就是要提供一个初始值来进行构造

#include <utility>
using std::make_pair;
#endif

// ordinary function
int add(int i, int j) { return i + j; }

// lambda, which generates an unnamed function-object class
auto mod = [](int i, int j) { return i % j; };

// function-object class
// In the first printing we named this struct div, but this name conflicts with
// the name of a C library function.  Compilers are permitted to put
// C library names in the global namespace.  Future printings will
// change the name of this calss to divide.
struct divide {
    int operator()(int denominator, int divisor) {
        return denominator / divisor;
    }
};

int main()
{
    function<int(int, int)> f1 = add;   // function pointer
    function<int(int, int)> f2 = divide(); // callable class type
    function<int(int, int)> f3 = [](int i, int j) // lambda
                                 { return i * j; };
    cout << f1(4,2) << endl; // prints 6
    cout << f2(4,2) << endl; // prints 2
    cout << f3(4,2) << endl; // prints 8

    // table of callable objects corresponding to each binary operator
    // all the callables must take two ints and return an int
    // an element can be a function pointer, function object, or lambda
#ifdef LIST_INIT
    map<string, function<int(int, int)>> binops = {
        {"+", add},                  // function pointer
        {"-", std::minus<int>()},    // library function object
        {"/",  divide()},            // user-defined function object
        {"*", [](int i, int j) { return i * j; }}, // unnamed lambda
        {"%", mod} };                // named lambda object
#else
    map<string, function<int(int, int)>> binops;
        binops.insert(make_pair("+", add));                 // function pointer
        binops.insert(make_pair("-", std::minus<int>()));   // library function object
        binops.insert(make_pair("/",  divide()));           // user-defined function object
        binops.insert(make_pair("*", [](int i, int j) { return i * j; })); // unnamed lambda
        binops.insert(make_pair("%", mod));                // named lambda object
#endif
    cout << binops["+"](10, 5) << endl; // calls add(10, 5)
    cout << binops["-"](10, 5) << endl; // uses the call operator of the minus<int> object
    cout << binops["/"](10, 5) << endl; // uses the call operator of the divide object
    cout << binops["*"](10, 5) << endl; // calls the lambda function object
    cout << binops["%"](10, 5) << endl; // calls the lambda function object

    return 0;
}

如果一个函数存在多个重载版本,那么function对象构造时不能直接使用函数名。可以先构造一个函数指针,在用函数指针解引用来构造。

二义性转换:
1.A类型定义了一个接受B的转换构造函数,B类型定义了一个目标类型是A的转换运算符。
2.定义了多个转换规则,而这些转换涉及的类型相互之间有所联系。(int 与double)

当调用重载函数时,如果用户定义的多种类型都定义了可行匹配,我们认为这些匹配一样好。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值