0

I have this method header:

void Find(const _T & v, int max, const function<bool(const _E &)> & filter)

I'm using std::function because I need to accept function pointer, functor or lambda expression. I would like the filter to be optional, and default to function that always return true (nothing is filtered out) as default parameter. I've tried something like this:

#include <functional>

template <typename E>
bool alwaystrue(const E & e){ return true; }

template <typename T, typename E>
void Find(const T & v, int max,
          const std::function<bool(const E &)> & filter = alwaystrue);

int main()
{
    Find<int, int>(1, 2);
}

But this doesn't compile:

50016981.cpp: In function ‘void Find(const T&, int, const std::function<bool(const E&)>&) [with T = int; E = int]’:
50016981.cpp:11:24: error: cannot resolve overloaded function ‘alwaystrue’ based on conversion to type ‘const std::function<bool(const int&)>&’
     Find<int, int>(1, 2);
                        ^

I've also tried having the function inside my class but got a similar error.

Is there a problem combining with std::function with templates? And if so, could you suggest how to do what I want? I want to avoid overloading the Find() function (if possible) so I don't have duplicate code.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
skluzada
  • 153
  • 12
  • 1
    How about using a lambda for the default argument? Or overloading? – Some programmer dude Apr 25 '18 at 08:03
  • 1
    On an unrelated note, please read [What are the rules about using an underscore in a C++ identifier?](https://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier) Symbols like your `_E` or `_T` are reserved in all scopes. – Some programmer dude Apr 25 '18 at 08:03
  • 3
    You have not specified the template arguments when using `alwaystrue` in the `Find` declaration. – keith Apr 25 '18 at 08:12
  • 2
    What exactly the error is? What if you specialize your `alwaystrue` parameter: `void Find(const _T & v, int max, const function & filter = alwaystrue<_E>)` ? – Alexey Apr 25 '18 at 08:13
  • @keith That was the problem, thank you. – skluzada Apr 25 '18 at 08:20
  • @Alexey It works fine, when I specify the template argument, thank you. – skluzada Apr 25 '18 at 08:22
  • BTW, identifiers beginning with underscore followed by a capital letter are reserved *for any purpose* in C++ (which means they may be macros). Just lose those underscores and you'll be much safer! – Toby Speight Apr 25 '18 at 10:27

1 Answers1

2

You need to indicate which instantiation of alwaystrue you want to use as your default, i.e. alwaystrue<E>:

template <typename T, typename E>
void Find(const T& v, int max,
          const std::function<bool(const E&)>& filter = alwaystrue<E>);
Toby Speight
  • 27,591
  • 48
  • 66
  • 103