Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::is_invocable is false but std::invoke works

Tags:

c++

c++17

The following program's output seems to contradict itself:

#include <type_traits> #include <iostream> #include <functional>  void foo(int&){ std::cout << "called\n"; }  int main() {     int a;     foo(a);     std::cout << std::is_invocable_v<decltype(foo), decltype(a)> << std::endl;     std::invoke(foo, a); } 

The output is:

called 0 called 

Which seems to me to be invoking a function that is not invocable? What is going on here?

like image 486
Baruch Avatar asked Jan 09 '18 11:01

Baruch


1 Answers

decltype(a) is int. This corresponds to invoking f with an int prvalue -- something like f(7). That one indeed doesn't compile, because a non-const lvalue reference cannot bind to a prvalue.

What you're doing instead in main is calling f with an lvalue, a, to which the reference can bind just fine.

To get the correct result from std::is_invocable, use the expression form of decltype by adding parentheses:

std::is_invocable_v<decltype(foo), decltype((a))> //                                          ^ ^ 
like image 67
Quentin Avatar answered Sep 23 '22 01:09

Quentin