类似于this question,是否可以使用SFINAE来确定类型是否具有带有特定参数的成员函数?如果没有在另一个问题中回答的参数列表,则std::void_t
example说它很好用。 (我支持后者。)但是,如果我尝试使用额外的std::decltype<>()
添加对参数lust的检查,它将失败,并返回template parameters not deducible in partial specialization
。有什么方法可以扩展此方法以检查某些参数类型吗?
示例代码:
#include <type_traits>
class A {
public :
void a(){}
void b(int val){}
};
class B {
public :
void b(float val){}
};
// --- Has function a() without arguments
template <typename T, typename = void> struct has_a : std::false_type
{
};
template <typename T> struct has_a<T, std::void_t<decltype(std::declval<T>().a())>> : std::true_type
{
};
template <typename T> constexpr bool has_a_v = has_a<T>::value;
// This is OK:
static_assert(true == has_a_v<A>);
static_assert(false == has_a_v<B>);
// --- Has function b() with one argument of one given type
template <typename T, typename U, typename = void> struct has_b : std::false_type
{
};
template <typename T ,typename U> struct has_b<T, std::void_t<decltype(std::declval<T>().b(std::declval<U>()))>> : std::true_type
{
};
template <typename T, typename U> constexpr bool has_b_v = has_b<T, U>::value;
// This fails with `template parameters not deducible in partial specialization`:
static_assert(true == has_b_v<A, int>);
static_assert(false == has_b_v<B, int>);
static_assert(false == has_b_v<A, float>);
static_assert(true == has_b_v<B, float>);
int main () { return 0;}
答案 0 :(得分:2)
是的。类void_t
中的成员函数b
的{{1}}检查示例:
B
这是如果您要检查 exact 签名。您的方法也很好(一旦您按照问题下的注释对其进行了修复),但是它实际上会检查成员函数是否具有某些类型的参数可调用(并忽略返回类型)。
答案 1 :(得分:2)
在您的部分专业化工作中,您忘记添加U
参数:
template <typename T, typename U>
struct has_b<
T,
U, // You forgot it
std::void_t<decltype(std::declval<T>().b(std::declval<U>()))>> : std::true_type
{
};