为什么unary_function没有定义operator()?

时间:2010-10-07 23:52:55

标签: c++

我只是在为一组基于take和int并返回void的仿函数寻找一个方便的基类。

考虑使用std / functional这些仿函数基本上是unary_function<int,void> operator()

为什么在unary_function模板上没有定义virtual result_type operator()(const argument_type& _Left) const = 0;?我猜这是因为常数会有变化......
是否有其他模板我错过了包括operator()

我有一段时间没有这样做,我错过了什么吗?

我如何利用现有的功能

std::ptr_fun< HWND, void >(someFunction);
std::pointer_to_unary_function<HWND, void>(someFunction);

修改 也许我应该包括另外一半的用法来完成这个。也许这是使用一半不适合这个概念。

如何将仿函数传递给方法并使用它?

typedef unary_function<int,void> Functor;

void DoStuff(const Functor& functor) {
  int demo = 1;
  functor(demo);
}

作为unary_function的functor没有定义operator(),所以DoStuff不能编译。

2 个答案:

答案 0 :(得分:10)

模板概念是鸭子型的。满足UnaryFunction概念需要operator()的类的事实在文档中指定,并从使用满足该概念的模板参数的模板推断出来。没有必要拼写出函数签名,或者要求它是virtual,它需要一个const引用参数,或者它是一个const成员函数。

不应将unary_function模板视为接口(并且它不是设计为一个接口)。它当然不是一个多态基类。它是一个帮助程序,由希望实现AdaptableUnaryFunction概念的类使用。

来自STL文档,它们对原始设计原理是可靠的:“它存在的唯一原因是使定义自适应一元函数更方便” - http://www.sgi.com/tech/stl/unary_function.html

标准类似:“提供以下类来简化参数和结果类型的typedef”(20.3.1 / 1)

高级用法 - 实际上UnaryFunction需要的是,如果f是一元函数对象,并且x可转换为参数类型,那么f(x)是一个有效的表达式结果类型。它根本不需要一个参数operator(),没有一个两个arg operator(),第二个arg有一个默认值。尝试将其定义为纯虚函数; - )

第二个问题,你只需用函数名/指针调用ptr_fun就可以了。其模板参数将从函数类型推断出来,因此您无需指定它们。结果是相应pointer_to_unary_function模板类型的对象。

直接使用STL文档中的示例:

transform(first, last, first,
    compose1(negate<double>, ptr_fun(fabs)));

这大致相当于:

for (auto current = first; current != last; ++current) {
    *current = -fabs(*current);
}

(我在其C ++ 0x意义上使用auto,意思是“我不能打扰/在这里编写迭代器类型是不可能的”)

函数名称/指针可用于transform(带UnaryFunction模板参数),但不能用于compose1(带AdapatableUnaryFunction模板参数) 。因此,如果没有ptr_fun,就无法使用negate撰写fabs

为了回应你的编辑,我强调, unary_function不是多态基类。您无法将其(或其任何实例化)用作函数参数类型。

如果要使用UnaryFunction或AdaptableUnaryFunction概念,则必须编写函数模板:

template <typename UnaryFunction>
void DoStuff(UnaryFunction &functor) {
    int demo = 1;
    functor(demo);
}

这只要求仿函数采用int转换为的类型。它并不要求它完全取int并完全返回void。这通常是一个优势。

如果模板没有达到您想要的效果,则unary_function不适合您。您没有遗漏任何内容:您可以使用虚拟operator()设计自己的界面,但标准库并不旨在提供任何此类内容。

答案 1 :(得分:2)

因为虚拟运算符()不是unary_function概念的一部分。除了constness的差异之外,一元函数概念可以具有非虚拟运算符。