Template concepts are printed in duck style. The fact that a class that satisfies the UnaryFunction concept needs operator() is indicated in the documentation and is deduced from templates that use template parameters that satisfy this concept. There is no need to indicate the signature of a function or require it to be virtual , that it accepts a parameter for referencing a constant, or that it is a member function of const.
The unary_function pattern unary_function not be considered as an interface (and it is not designed as one). This, of course, is not a polymorphic base class. This helper is used by classes that want to implement the concept of AdaptableUnaryFunction .
From STL documents that are reliable for the original design justification: “the only reason it exists is to make it more convenient to define adaptive inherited functions” - http://www.sgi.com/tech/stl/unary_function.html
The standard is similar: "The following classes are provided to simplify the typedefs of arguments and result types" (20.3.1 / 1)
Extended use - in fact, what is required for a UnaryFunction is that if f is a unary functional object and x converted to an argument type, then f(x) is a valid expression of the result type. It should not have one operator() argument at all, it should have two-arg operator() , and the second arg has a default value. Try defining this as a pure virtual function; -)
The second question, you use ptr_fun by simply calling it with the function name / pointer. Its template parameters will be inferred from the function type, so you do not need to specify them. The result is an object of the corresponding pointer_to_unary_function template pointer_to_unary_function .
To use the example directly from STL documents:
transform(first, last, first, compose1(negate<double>, ptr_fun(fabs)));
This is roughly equivalent to:
for (auto current = first; current != last; ++current) { *current = -fabs(*current); }
(where I use auto in my sense C ++ 0x, that is, "it doesn’t bother me / it is impossible to write an iterator type here")
The function name / pointer can be used in transform (which takes the UnaryFunction template UnaryFunction ), but not in compose1 (which takes the AdapatableUnaryFunction template AdapatableUnaryFunction ). Thus, without ptr_fun not possible to link negate with fabs .
In response to your Editing, I emphasize, unary_function is not a polymorphic base class . You cannot use it (or any of its instances) as a parameter type of a function.
If you want to use the UnaryFunction or AdaptableUnaryFunction concepts, you must write a function template:
template <typename UnaryFunction> void DoStuff(UnaryFunction &functor) { int demo = 1; functor(demo); }
It only requires the functor to take the type that int converted. This does not require it to execute exactly int and return exactly void . This is usually an advantage.
If the template does not do what you want, then unary_function not for you. You didn’t miss anything: you can create your own interface using virtual operator() , but standard libraries are not aimed at providing such a thing.