2

I am trying to make a template function that is will only get used for invocables that match a certain i pattern (in the example, accept int and return int). I tried this but it doesn't compile. Can anyone explain to me why?

#include <iostream>
#include <type_traits>

int foo(int) {return 0;}
int foo(char*) {return 0;}

template<class T>
std::enable_if_t<std::is_invocable_r_v<int, T, int>>
add(T t) {}

int main()
{
    add(foo);
}

The error I get (VS2017):

main.cpp(13): error C2672: 'add': no matching overloaded function found
main.cpp(13): error C2783: 'enable_if<_Test,_Ty>::type add(T)': could not deduce template argument for 'T'
        with
        [
            _Ty=void
        ]
main.cpp(9): note: see declaration of 'add'
Baruch
  • 20,590
  • 28
  • 126
  • 201
  • 1
    Include the error messages that your compiler so helpfully provides. Also, your `int` functions don't return anything. – Jonathon Reinhart Dec 28 '17 at 22:17
  • How can it possibly work? You have two versions of foo, how compiler would know which one to use? You can greatly simplify your example by removing all `enable_if` stuff and just try to pass this `foo` as an argument to template function. – SergeyA Dec 28 '17 at 22:42
  • @SergeyA That is the point of the SFINAE. If I replace the whole thing with `void add(int(*t)(int)) {}` it compiles. I am trying to achive the same via templates – Baruch Dec 28 '17 at 22:47
  • 2
    See [this](https://stackoverflow.com/q/25871381/2069064) or [this](https://stackoverflow.com/q/46024823/2069064) or [this](https://stackoverflow.com/q/4159487/2069064) or ... – Barry Dec 28 '17 at 22:47
  • 2
    @baruch, no it is NOT point of sfinae. Point of sfinae is to select right overload based on a non-ambiguos name. In your case, `foo` is ambiguos name. – SergeyA Dec 28 '17 at 22:48

0 Answers0