Function taking as an argument std::equal_to, std::grater etc

Started by
3 comments, last by Misery 11 years, 9 months ago
Hello,

I am trying to make a function that would take some kind of comparision operator from std:: library. For example:


std::equal_to

as one of the arguments.
However, I fail all the time. Could someone give an example of such function, that would work?

Thanks in advance,
Regards
Advertisement

template <typename T>
bool doStuff(int a, int b, T comparitor)
{
return comparitor(a,b);
}


I'm guessing the problem you're having is that the component std functions / functors are not of the same type. Template parameters make this problem go away.

Some of the std component functions may be of related types : e.g. deriving from std::unary_function etc - so it may be possible to use normal polymorphism to work around this - I wouldn't recommend it though. TBH I'm not even sure inheriting from bases like std::unary_function is enforced by the standard.

Lastly, you could take an std::function<bool (int,int)> or similar, if you want to avoid writing templates.
[size="1"]
A good place to look for examples (and inspiration) are the docs for SGI STL: http://www.sgi.com/tech/stl/
Often you can find something similar to what you're trying to accomplish. In your case [font=courier new,courier,monospace]std::count_if[/font] (for instance) takes a "[font=courier new,courier,monospace]Predicate pred[/font]" parameter, just like you want in case of [font=courier new,courier,monospace]std::equal_to[/font] being an argument: http://www.sgi.com/t...l/count_if.html

[source lang="cpp"]template &lt;class InputIterator, class Predicate, class Size&gt;
void count_if(InputIterator first, InputIterator last,
Predicate pred,
Size& n);
[/source]

Note that in the context of template parameters specification (the first line, the one that starts with "[font=courier new,courier,monospace]template[/font]") you can either use "[font=courier new,courier,monospace]class[/font]" (you are allowed to pass a built-in type, like "[font=courier new,courier,monospace]std::size_t[/font]" for "[font=courier new,courier,monospace]Size[/font]" or "[font=courier new,courier,monospace]int *[/font]" for "[font=courier new,courier,monospace]InputIterator[/font]", so it's a bit of a misnomer) or "[font=courier new,courier,monospace]typename[/font]" pretty much interchangeably (the only case where you have to use the "[font=courier new,courier,monospace]class[/font]" are the so-called TTPs (template-template parameters, like when you want to pass a class template "[font=courier new,courier,monospace]std::vector[/font]" as opposed to, say, template class "[font=courier new,courier,monospace]std::vector<double>[/font]"), but don't worry about it here).

Another reason I point out the docs is that they show good naming conventions for template parameters -- it's good idea to use names that express the concept, like "[font=courier new,courier,monospace]Predicate[/font]", instead of general names, like "[font=courier new,courier,monospace]T[/font]", for self-documenting code. Even though it's "just" for documentation (it won't be enforced, concepts as a type enforcement mechanism didn't get into C++11), it's pretty useful -- it allows the code reader (often you) to just quickly skim at the function signature to figure out what it does and what it wants (just like in the above "[font=courier new,courier,monospace]count_if[/font]" example). You can look up the concept you need by looking up the class (template) you want to use, for instance, http://www.sgi.com/t...l/equal_to.html

Another good example of using a concept name to document your requirements is [font=courier new,courier,monospace]std::sort[/font], http://www.sgi.com/tech/stl/sort.html -- that's the relevant example for arguments like [font=courier new,courier,monospace]std::less[/font]:

[source lang="cpp"]template &lt;class RandomAccessIterator, class StrictWeakOrdering&gt;
void sort(RandomAccessIterator first, RandomAccessIterator last,
StrictWeakOrdering comp);

[/source]

This makes clear to the users of [font=courier new,courier,monospace]std::sort[/font] that they are expected to pass a particular comparator function object -- one consistent with a strict weak ordering -- not just "any" comparator.

See also:
http://www.sgi.com/t...l/functors.html
http://www.sgi.com/t...yPredicate.html

BTW, note that unary_function & binary_function are deprecated in C++11:
http://www.open-std....2010/n3145.html
http://en.cppreferen.../unary_function

BTW, note that unary_function & binary_function are deprecated in C++11:
http://www.open-std....2010/n3145.html
http://en.cppreferen.../unary_function


Nice to know, thanks!
[size="1"]
Thanks a lot :]
Your suggestions Gyus, did the job!

This topic is closed to new replies.

Advertisement