Reputation: 826
I have a templated function (Process
) where I would like to perform a compile time check to see if the supplied typename (Z
) has a templated static member function taking arguments of the two supplied types (X
) and (Y
).
Is it possible to do this with an if constexpr
test and if so, what would it be?
#include <iostream>
struct A { template<typename X, typename Y> static bool compare(const X&, const Y&) { return true; } };
struct B { };
template <typename Z, typename X, typename Y>
inline void Process(X x, Y y)
{
if constexpr (std::is_invocable_v<decltype(Z::compare), const X&, const Y&> )
{
Z::compare(x,y);
}
else {
std::cout << "hi";
}
}
int main()
{
Process<A>(3,2);
Process<B>(3,2);
}
Upvotes: 1
Views: 157
Reputation: 52621
I can't think of a way to do it with if constexpr
alone, without a pair of overloads to test with SFINAE. See if something like this works for you:
template <typename Z, typename X, typename Y>
auto test(X x, Y y) ->
std::enable_if_t<sizeof(decltype(Z::compare(x, y))*) != 0, std::true_type>;
template <typename Z>
std::false_type test(...);
template <typename Z, typename X, typename Y>
inline void Process(X x, Y y)
{
if constexpr (decltype(test<Z>(x, y))::value)
{
Z::compare(x,y);
}
else {
std::cout << "hi";
}
}
Demo.
This doesn't test that Z
has a templated member function specifically, just that it has a static member function with the right name callable with the right arguments.
Upvotes: 1