• c++重载小括号,实现仿函数


    重载 operator() 的类的对象以及函数指针叫函数对象。

    类重载 operator() 有一些好处:

    • operator() 可以是重载的函数。传递这个函数对象给泛型库时,可以把重载集作为一个整体传过去。而传函数指针的话只能传单体。
    • 函数对象可以有状态,这可以实现闭包。 C++ 语核里有 lambda 表达式,它可以创建自动捕获外围变量(或者携带自定义状态)的函数对象。

    目前类重载的 operator() 有一些缺点:

    • 它不能是 static 成员函数。这使得标准库中大量存在的无状态函数对象,以及可能广泛使用的自定义无状态函数对象,可能会带来额外开销。也使得无捕获的 lambda 实现变得复杂。(至少需要有一个非 static 的 operator() 和 static 的额外成员函数。 Lambda 表达式需要能被隐式转换成指向后者的指针。)

    用法为:

     class ShorterThan {
         public:
             explicit ShorterThan(int maxLength) : length(maxLength) {}
             bool operator() (const string& str) const {
                 return str.length() < length;
             }
         private:
             const int length;
     };
    • count_if(myVector.begin(), myVector.end(), ShorterThan(length)); //直接调用即可

    这里需要注意的是,不要纠结于语法问题:ShorterThan(length)似乎并没有调用operator()函数?其实它调用了,创建了一个临时对象。你也可以自己加一些输出语句看一看。

    类型转换

    C++中可以定义类型转换函数,将类对象转换为其他类型,函数原型为:operator Type()

    • 类型转换函数与转换构造函数具有同等的地位;
    • 类型转换函数使得编译器有能力将对象转化为其他类型;
    • 编译器能够隐式的使用类型转换函数
    #include <iostream>
    #include <string>
    
    class Test;
    
    class Value
    {
    public:
        Value()
        {
    
        }
    
        Value(Test& t) // false
        // explicit Value(Test& t) // Ok
        {
            std::cout << "explicit Value(Test& t)" << std::endl;                                        
        }            
    };
    
    class Test
    {
        int mValue;
    
    public:
        Test(int i = 0)
        {
            mValue = i;                                
        }
    
        int value()
        {
            return mValue;                                    
        }
    
        operator Value()
        {
            Value ret;
            std::cout << "operator Value()" << std::endl;
            return ret;                                                
        }                    
    };
    
    int main()
    {   
        Test t(100);
        Value v = t;
    
        return 0;                
    }

    从输出结果我们可以发现:转换构造函数和类型转换函数发生冲突了,编译器不知道应该调用哪个函数。因此发生了错误。
    当然我们可以使用explicit关键字抑制隐式的转换构造函数,让程序只调用类型转换函数。但是,我们无法抑制隐式的类型转换函数。

  • 相关阅读:
    Ural_1018. Binary Apple Tree(树形DP)
    2011 Asia Shanghai Regional Contest Problem A
    Ural_1012. Kbased Numbers. Version 2(dp)
    HDU_1524 A Chess Game (sg函数)
    HDU_1760 A New Tetris Game(dfs + 博弈)
    POJ_2023 Choose Your Own Adventure(DFS)
    POJ_3267 The Cow Lexicon(DP)
    Qt 的QString类的使用
    用QFileSystemModel和Listview做的简易图片浏览
    Qt 对文件的操作
  • 原文地址:https://www.cnblogs.com/wangshaowei/p/13724142.html
Copyright © 2020-2023  润新知