I have a function and I need to test whether I can pass an argument of a given type to it. For example:
template<typename T, auto F>
decltype(F(declval<T>{})) foo();
Calling foo<int, bar>() does 2 things:
- Sets the return type of
foowould have the same return type asbar - Ensures that
baris a function that accepts an argument of typeT
Unfortunately I don't have access to auto template types, but I still want to accomplish both of these. What I need is a decltype for function pointers, which would allow me to do something like this:
template <typename T, typename F>
decltype(declval<F>(declval<T>{})) foo();
So I could still call foo<int, bar>() and get the same result. Of course there isn't a declval for function pointers. But is there another way I could accomplish this?
What do you mean?
std::declvalworks perfectly with function pointer types:In this example,
Fcan be a function pointer type, a lambda type or any callable types.Here's an example of usage:
Another example using the detection idiom (implementable in C++11):
Note that all this can be replaced by
std::invoke_result_tandstd::is_invocablein C++17. I'd suggest mimicking those to have the most seamless upgrade.