See the test case
#include <iostream>
#include <type_traits>
int main(){
const char* hw = "hello world";
auto task = [hw] ()->const char * { return hw ; };
std::cout << std::is_invocable_r_v<const char *, decltype(task)> << std::endl;
std::cout << std::is_invocable_r_v<void, decltype(task)> << std::endl;
std::cout << std::is_invocable_r_v<const char, decltype(task)> << std::endl;
}
Result is
1
1
0
but I would expect
1
0
0
See
https://godbolt.org/z/d1cbfbsEY
>Solution :
Why doesn’t std::is_invocable_r_v<void, TFun> return false if the function does not return void
From https://en.cppreference.com/w/cpp/types/is_invocable I see that:
- Determines whether
INVOKE<R>(std::declval<Fn>(), std::declval<ArgTypes>()...)is well formed when treated as an unevaluated operand.
Then I click on "INVOKE" and jump to https://en.cppreference.com/w/cpp/utility/functional which has:
The exposition-only operation
INVOKE<R>(f, t1, t2, ..., tN)is defined asstatic_cast<void>(INVOKE(f, t1, t2, ..., tN))if R is (possibly cv-qualified) void, otherwise INVOKE(f, t1, t2, …, tN) implicitly converted to R.
Surely static_cast<void>(task()) is fine, void just discard the value. std::is_invocable_r_v<void, decltype(task)> should be true.