欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

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

程序员文章站 2022-03-23 20:37:01
下标运算符要有const与非const重载两种版本。 struct absInt { int operator()(int val) const { retu...

下标运算符要有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 vi;
    while (cin >> i)
        vi.push_back(i);

    // call absInt to store the absolute value of those ints in vu
    vector 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 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 
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 f1 = add;   // function pointer
    function f2 = divide(); // callable class type
    function 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> binops = {
        {"+", add},                  // function pointer
        {"-", std::minus()},    // library function object
        {"/",  divide()},            // user-defined function object
        {"*", [](int i, int j) { return i * j; }}, // unnamed lambda
        {"%", mod} };                // named lambda object
#else
    map> binops;
        binops.insert(make_pair("+", add));                 // function pointer
        binops.insert(make_pair("-", std::minus()));   // 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 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)

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