我一直听到在C++中有关functor的许多内容。能否给我一个概述,告诉我它们是什么以及在什么情况下它们会有用?
我一直听到在C++中有关functor的许多内容。能否给我一个概述,告诉我它们是什么以及在什么情况下它们会有用?
pthread_create(..)
的参数之一是要在其自己的线程上执行的函数指针。但是有一个不便之处。除非它是静态方法,否则此指针不能是指向方法的指针,除非您指定它的类,例如class::method
。另外,您的方法的接口只能是:void* method(void* something)
static void* startThread(void* arg)
,指向该方法的指针将被用作调用pthread_create(..)
的参数。而startThread(..)
应该接收一个指向任何Functor派生类堆实例的void*强制转换引用,当执行时将其转换回Functor*,然后调用它的run()
方法。operator()
中重复使用,并根据需要进行调整大小。#include <string>
#include <vector>
#include <algorithm>
template <typename T>
T min3(const T& a, const T& b, const T& c)
{
return std::min(std::min(a, b), c);
}
class levenshtein_distance
{
mutable std::vector<std::vector<unsigned int> > matrix_;
public:
explicit levenshtein_distance(size_t initial_size = 8)
: matrix_(initial_size, std::vector<unsigned int>(initial_size))
{
}
unsigned int operator()(const std::string& s, const std::string& t) const
{
const size_t m = s.size();
const size_t n = t.size();
// The distance between a string and the empty string is the string's length
if (m == 0) {
return n;
}
if (n == 0) {
return m;
}
// Size the matrix as necessary
if (matrix_.size() < m + 1) {
matrix_.resize(m + 1, matrix_[0]);
}
if (matrix_[0].size() < n + 1) {
for (auto& mat : matrix_) {
mat.resize(n + 1);
}
}
// The top row and left column are prefixes that can be reached by
// insertions and deletions alone
unsigned int i, j;
for (i = 1; i <= m; ++i) {
matrix_[i][0] = i;
}
for (j = 1; j <= n; ++j) {
matrix_[0][j] = j;
}
// Fill in the rest of the matrix
for (j = 1; j <= n; ++j) {
for (i = 1; i <= m; ++i) {
unsigned int substitution_cost = s[i - 1] == t[j - 1] ? 0 : 1;
matrix_[i][j] =
min3(matrix_[i - 1][j] + 1, // Deletion
matrix_[i][j - 1] + 1, // Insertion
matrix_[i - 1][j - 1] + substitution_cost); // Substitution
}
}
return matrix_[m][n];
}
};
int CTask::ThreeParameterTask(int par1, int par2, int par3)
// a template class for converting a member function of the type int function(int,int,int)
//to be called as a function object
template<typename _Ret,typename _Class,typename _arg1,typename _arg2,typename _arg3>
class mem_fun3_t
{
public:
explicit mem_fun3_t(_Ret (_Class::*_Pm)(_arg1,_arg2,_arg3))
:m_Ptr(_Pm) //okay here we store the member function pointer for later use
{}
//this operator call comes from the bind method
_Ret operator()(_Class *_P, _arg1 arg1, _arg2 arg2, _arg3 arg3) const
{
return ((_P->*m_Ptr)(arg1,arg2,arg3));
}
private:
_Ret (_Class::*m_Ptr)(_arg1,_arg2,_arg3);// method pointer signature
};
mem_fun3
来帮助调用上述类。template<typename _Ret,typename _Class,typename _arg1,typename _arg2,typename _arg3>
mem_fun3_t<_Ret,_Class,_arg1,_arg2,_arg3> mem_fun3 ( _Ret (_Class::*_Pm) (_arg1,_arg2,_arg3) )
{
return (mem_fun3_t<_Ret,_Class,_arg1,_arg2,_arg3>(_Pm));
}
template<typename _Func,typename _Ptr,typename _arg1,typename _arg2,typename _arg3>
class binder3
{
public:
//This is the constructor that does the binding part
binder3(_Func fn,_Ptr ptr,_arg1 i,_arg2 j,_arg3 k)
:m_ptr(ptr),m_fn(fn),m1(i),m2(j),m3(k){}
//and this is the function object
void operator()() const
{
m_fn(m_ptr,m1,m2,m3);//that calls the operator
}
private:
_Ptr m_ptr;
_Func m_fn;
_arg1 m1; _arg2 m2; _arg3 m3;
};
此外,还有一个使用binder3类的辅助函数 - bind3
:
//a helper function to call binder3
template <typename _Func, typename _P1,typename _arg1,typename _arg2,typename _arg3>
binder3<_Func, _P1, _arg1, _arg2, _arg3> bind3(_Func func, _P1 p1,_arg1 i,_arg2 j,_arg3 k)
{
return binder3<_Func, _P1, _arg1, _arg2, _arg3> (func, p1,i,j,k);
}
typedef binder3<mem_fun3_t<int,T,int,int,int> ,T* ,int,int,int> F3;
//and change the signature of the ctor
//just to illustrate the usage with a method signature taking more than one parameter
explicit Command(T* pObj,F3* p_method,long timeout,const char* key,
long priority = PRIO_NORMAL ):
m_objptr(pObj),m_timeout(timeout),m_key(key),m_value(priority),method1(0),method0(0),
method(0)
{
method3 = p_method;
}
这是如何称呼它:
F3 f3 = PluginThreadPool::bind3( PluginThreadPool::mem_fun3(
&CTask::ThreeParameterTask), task1,2122,23 );
f3();
将调用方法task1->ThreeParameterTask(21,22,23);
。
operator()(...)
是什么意思:它是重载_"函数调用"_运算符。这只是对()
运算符进行操作符重载。不要将operator()
与调用名为operator
的函数混淆,而是将其视为常规的运算符重载语法。 - zardoshtoperator()
? - Gabriel Staples