2

使用 STL 似乎需要的一件事是指定本地函数的方法。我通常提供的许多函数无法使用 STL 函数对象创建工具(例如 bind)创建,我必须手动滚动我的函数对象。

由于 C++ 标准禁止将本地类型用作模板实例化中的参数,因此我能够使用的最好方法是创建一个小型库,(仅显示相关部分)

// library header
class MyFunctionBase<R,T>  
{  
 public:  
   virtual ~MyFunctionBase();  
   virtual R operator()(const T &) const=0;  
};    


class  MyFunction<R,T> 
{   
    MyFunctionBase<R,T> *b; 
 public: 
    ~MyFunction()
    {
       delete b;
    }
    virtual R operator()(const T &) const
    {
        return (*b)(T);
    } 
};


// source file
....

    class func: public MyFunctionBase  ...
    std::stl_alg(....    MyFunction(new funct));

这在我看来一直很笨拙。我想 ISO 委员会的人也这么认为,并在 C++ 中添加了一个 lambda。

与此同时,编译器是如何解决这个问题的?(尤其是 Windows 编译器。)

一个可能会澄清一点的更正。变更日志:11 月 2 日被替换以澄清由于 C++ 标准禁止将本地类作为函数对象

4

3 回答 3

4

标准方式是一个“函子”——基本上,struct提供一个operator()

例如:

struct MyMinFunctor {
  bool operator()(const int& a, const int& b) { return a > b; }
};

vector<int> v;
sort(v.begin(), v.end(), MyMinFunctor());

因为它是一个结构/类,你可以继承任何东西,比如“binary_operator”,也可以为更高级的仿函数维护状态。

于 2008-11-02T05:41:27.897 回答
1

使用 C++0x,您可以使用 lambda(如您所述):

for_each(container.begin(), container.end(),
  [](auto item) {
    // do something with item
  }
  );

这已在 MS Visual C++ 2010(目前处于社区技术预览版)和 GCC 4.3.x(带有 -std=c++0x 编译器标志)中可用。但是,如果没有 lambda,您只需要提供一个类型:

  1. 默认可构造
  2. 可复制构造
  3. 定义函数运算符重载

有些算法需要二元函数对象,而有些算法需要一元函数对象。请参阅供应商的 STL 文档以准确了解哪些算法需要二进制函数对象,哪些算法需要一元函数对象。

您可能还想研究的一件事是TR1 的更新实现(基于 Boost.Bind 和 Boost.Function)bindfunction

于 2008-11-02T20:18:30.717 回答
1

Boost.Bind、Boost.Function 和 Boost.Lambda 是您的朋友。

于 2008-11-02T20:35:49.137 回答