考虑重载函数
void f(int);
void f(long);
void f(double);
void f(MyClass);
还有模板类中参数类型未知的方法
template <class T>
struct C {
void method(T arg) { ... }
};
我想在编译时检查是否有f
的版本可以将arg
作为参数。
template <class T>
struct C {
void method(T arg) {
if (CAN_BE_CALLED(f, arg) {
f(arg);
} else {
g();
}
}
};
答案 0 :(得分:3)
您可以使用detection idiom进行这样的测试
template<typename = void, typename... Args>
struct test : std::false_type {};
template<typename... Args>
struct test<std::void_t<decltype(f(std::declval<Args>()...))>, Args...>
: std::true_type {};
template<typename... Args>
inline constexpr bool test_v = test<void, Args...>::value;
并将其用作
template <class T>
struct C
{
void method(T arg)
{
if constexpr (test_v<T>)
f(arg);
else
g();
}
};
或者
template<typename... Args>
using test_t = decltype(f(std::declval<Args>()...));
template<typename... Args>
inline constexpr auto test_v = std::experimental::is_detected_v<test_t, Args...>;
答案 1 :(得分:2)
您可以对SFINAE执行以下操作:
template <class T, typename Enabler = void>
struct C {
void method(T arg) {
g();
}
};
template <class T>
struct C<T, std::void_t<decltype(f(std::declval<T>()))>> {
void method(T arg) {
f(arg);
}
};