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关键字抑制隐式的转换构造函数,让程序只调用类型转换函数。但是,我们无法抑制隐式的类型转换函数。

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/17533.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论