1

I wonder if it is possible to use operator< or some other as default parameter of some function.

Some stupid trivial example:

template <typename T>
void compare(std::function<bool(T, T)> lessThan = T::operator<);

I try to do this thing for int as T, but of course I get an error:

error: ‘operator<’ is not a member of ‘int’

I really don't know if it is possible till operator< as I know isn't a static function.

Do you have any idea, if and how it can be done?

Any help will be apreciated! :)

BartekPL
  • 2,290
  • 1
  • 17
  • 34
  • 9
    you can use `std::less{}` - or `std::less<>{}` if you have C++14 - as a default argument instead. – Corristo Feb 18 '18 at 12:23
  • 2
    Also don't name a predicate that can do whatever `lessThan` and [don't use `std::function` as the parameter type here](https://stackoverflow.com/questions/15409133/stdfunction-instead-of-templates-for-predicates). – LogicStuff Feb 18 '18 at 12:26

3 Answers3

3

It is almost always a bad idea to use std::function with template arguments in a template function.

std::function is type erasure, and template arguments are type deduction. Type erasure and type deduction are opposites of each other. Doing both is like building a house only to blow it up and build another one.

template <class T, class C=std::less<T>>
void compare(C&& c = {});

If you want to replace the compartor you can do

compare<int>( some_other_comparator );
Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
  • Thank you very much for this warning :) I completely forgot about `std::less` function. I know that there is `std::greater` also, but what if I want use some other operator like **bitwise and** as default parameter? Is there any convention for `operator` functions? – BartekPL Feb 18 '18 at 18:42
  • 2
    @BartekPL You can always write your own function object. But `std::bit_and` exists. – Yakk - Adam Nevraumont Feb 18 '18 at 19:39
  • Ahh, ok. Thank you once again ! :) – BartekPL Feb 18 '18 at 19:49
1

You can always mimic what the standard library does.

template<typename T,typename C=std::less<T>>
void compare()
{
  C comparator{};
  //Your logic here
}

This way you don't have to instantiate the predicate before passing it to the compare function. However you now have to call the compare function in the following way

compare<YourType>();

And if you need to change the predicate used by the compare function you call it like this

compare<YourType,NewComparator<>>()
blazgrom
  • 196
  • 3
  • 7
0

Came here looking for a satisfying solution for a similar problem, but I managed to work it out using function pointers and lambda function.

template <typename T>
void compare(bool (*const lessThan)(const T&, const T&) = [](const T& a, const T& b){return a<b;});

You have the ability to pass your own function to compare() or to leave it out and stick with the a<b.