Если вы намереваетесь проверить, есть ли у типа метод someFunc()
, который совместим (доступен с) для данной подписи), и вернуть данный тип, вы можете изменить свой код следующим образом
#include<iostream>
#include<type_traits>
#include<utility>
class X
{ public: int someFunc (int, long) const { return 9; } };
class Y
{ };
template <typename, typename = void>
struct Has_someFunc : public std::false_type
{ };
template <typename T, typename RType, typename ... Args>
struct Has_someFunc<std::tuple<T, RType, Args...>, std::enable_if_t<
std::is_same_v<RType,
decltype(std::declval<T>().someFunc(std::declval<Args>()...))>>>
: public std::true_type
{ };
template <typename RType, typename ... Args, typename T>
void f (T const & v)
{
if constexpr (Has_someFunc<std::tuple<T, RType, Args...>>::value)
std::cout << "has someFunc()\n";
else
std::cout << "has NOT someFunc()\n";
}
int main()
{
std::cout << "X "; f<int>(X{});
std::cout << "X "; f<int, int, long>(X{});
std::cout << "X "; f<int, int, int>(X{});
std::cout << "Y "; f<int>(Y{});
}
Недостаток: вы получаете "has someFun c ()" также из третьего вызова, поскольку последний аргумент (int
) совместим с последним ожидаемым аргументом (long
).