I'm trying to use template metaprogramming to find a function (not class method) with a specific signature. And to achieve that, I want to use the detection idiom.
Let's say that I have functions foo()
and bar()
:
void foo(int x);
template<typename... Ts>
void bar(Ts&& ...args);
And another function called foobar()
that receives a function and a parameter pack. foobar()
checks if the received function can be called with the parameters received through the parameter pack:
template<typename F, typename... Ts>
void foobar(F&& fun, Ts&& ...args) {
if constexpr(func_with_signature_exists_v<fun(declval<Args>()...)>)
do_something;
}
I would expect the following results from the if
statement in foobar()
:
if constexpr(func_with_signature_exists_v<foo(int)>) // true
if constexpr(func_with_signature_exists_v<foo(float)>) // false
if constexpr(func_with_signature_exists_v<foo(int, int)>) // false
if constexpr(func_with_signature_exists_v<bar(int)>) // true
if constexpr(func_with_signature_exists_v<bar(int, int)>) // true
if constexpr(func_with_signature_exists_v<bar(int, float, int)>) // true
I tried to follow the steps from the accepted answer from this link, but the is_detected idiom didn't complain when I tried passing a float
to a function expecting an int
.
Also, I'd prefer if I could pass any function to the using statement, instead of explicitly specializing it for one specific function, like here:
template<typename... Args>
using test_t = decltype(f(std::declval<Args>()...));
Is there any way to achieve what I'm looking for? Or anything similar to it?
Note that this is for a side project, so I'm trying to use C++17, not C++14 or C++11.