检查 class 是否有函数(检查 return 类型和常量)
Checking if a class has a function (return type and const checked)
给定
class A {
public:
bool foo(int) const {return true;}
};
我想要 HasFooWithStringReturnTypeAndIsConst<A>::value
和
HasFooWithBoolReturnTypeAndIsNotConst<A>::value
为假(HasFooWithBoolReturnTypeAndIsConst<A>::value
已经 return 为真,因此工作正常)。这是我拥有的:
#include <iostream>
#include <type_traits>
#include <string>
class A {
public:
bool foo(int) const {return true;}
};
template <typename...> struct voider {using type = void;};
template <typename... Ts>
using void_t = typename voider<Ts...>::type;
template <typename T, typename = void_t<T>>
struct HasFooWithBoolReturnTypeAndIsNotConst : std::false_type {};
template <typename T>
struct HasFooWithBoolReturnTypeAndIsNotConst<T,
void_t<decltype(std::declval<T&>().foo(std::declval<int>()))>> {
using Foo = bool (T::*)(int);
template <typename U> static std::true_type test (Foo*);
template <typename U> static std::false_type test (...);
static constexpr bool value = std::is_same<decltype(test<T>(nullptr)), std::true_type>::value;
};
template <typename T, typename = void_t<T>>
struct HasFooWithStringReturnTypeAndIsConst : std::false_type {};
template <typename T>
struct HasFooWithStringReturnTypeAndIsConst<T,
void_t<decltype(std::declval<T&>().foo(std::declval<int>()))>> {
using Foo = std::string (T::*)(int) const;
template <typename U> static std::true_type test (Foo*);
template <typename U> static std::false_type test (...);
static constexpr bool value = std::is_same<decltype(test<T>(nullptr)), std::true_type>::value;
};
int main() {
std::cout << HasFooWithStringReturnTypeAndIsConst<A>::value << '\n'; // true (should be false!)
std::cout << HasFooWithBoolReturnTypeAndIsNotConst<A>::value << '\n'; // true (should be false!)
}
有人可以解释为什么他们 returning true
而不是 false
吗?如何修复它们以使它们 return 错误? A::foo(int)
是一个常量函数,return 是布尔值,所以它们应该 return 为假,不是吗?
您的支票用于:
decltype(test<T>(nullptr))
两个重载是:
template <typename U> static std::true_type test(Foo*);
template <typename U> static std::false_type test(...);
您实际上没有在考虑 &T::foo
。您只是在检查是否可以将 nullptr
转换为某种任意指针类型。当然可以。这就是它以 true_type
结尾的原因。您要检查的是是否可以将 &T::foo
专门转换为该类型:
template <typename U> static std::true_type test (std::string (U::*)(int) const );
template <typename U> static std::false_type test (...);
static constexpr bool value = decltype(test<T>(&T::foo))::value;
请注意,您可以直接通过以下方式在偏特化中更简单地执行此操作:
template <typename T>
struct HasFooWithStringReturnTypeAndIsConst<T,
std::enable_if_t<
std::is_same<std::string,
decltype(std::declval<const T&>().foo(0))
>::value
>> : std::true_type { };
在这里,我们通过在 const T&
上调用它来检查 foo()
是否为 const
,然后简单地检查其 return 类型是否为 std::string
.
给定
class A {
public:
bool foo(int) const {return true;}
};
我想要 HasFooWithStringReturnTypeAndIsConst<A>::value
和
HasFooWithBoolReturnTypeAndIsNotConst<A>::value
为假(HasFooWithBoolReturnTypeAndIsConst<A>::value
已经 return 为真,因此工作正常)。这是我拥有的:
#include <iostream>
#include <type_traits>
#include <string>
class A {
public:
bool foo(int) const {return true;}
};
template <typename...> struct voider {using type = void;};
template <typename... Ts>
using void_t = typename voider<Ts...>::type;
template <typename T, typename = void_t<T>>
struct HasFooWithBoolReturnTypeAndIsNotConst : std::false_type {};
template <typename T>
struct HasFooWithBoolReturnTypeAndIsNotConst<T,
void_t<decltype(std::declval<T&>().foo(std::declval<int>()))>> {
using Foo = bool (T::*)(int);
template <typename U> static std::true_type test (Foo*);
template <typename U> static std::false_type test (...);
static constexpr bool value = std::is_same<decltype(test<T>(nullptr)), std::true_type>::value;
};
template <typename T, typename = void_t<T>>
struct HasFooWithStringReturnTypeAndIsConst : std::false_type {};
template <typename T>
struct HasFooWithStringReturnTypeAndIsConst<T,
void_t<decltype(std::declval<T&>().foo(std::declval<int>()))>> {
using Foo = std::string (T::*)(int) const;
template <typename U> static std::true_type test (Foo*);
template <typename U> static std::false_type test (...);
static constexpr bool value = std::is_same<decltype(test<T>(nullptr)), std::true_type>::value;
};
int main() {
std::cout << HasFooWithStringReturnTypeAndIsConst<A>::value << '\n'; // true (should be false!)
std::cout << HasFooWithBoolReturnTypeAndIsNotConst<A>::value << '\n'; // true (should be false!)
}
有人可以解释为什么他们 returning true
而不是 false
吗?如何修复它们以使它们 return 错误? A::foo(int)
是一个常量函数,return 是布尔值,所以它们应该 return 为假,不是吗?
您的支票用于:
decltype(test<T>(nullptr))
两个重载是:
template <typename U> static std::true_type test(Foo*);
template <typename U> static std::false_type test(...);
您实际上没有在考虑 &T::foo
。您只是在检查是否可以将 nullptr
转换为某种任意指针类型。当然可以。这就是它以 true_type
结尾的原因。您要检查的是是否可以将 &T::foo
专门转换为该类型:
template <typename U> static std::true_type test (std::string (U::*)(int) const );
template <typename U> static std::false_type test (...);
static constexpr bool value = decltype(test<T>(&T::foo))::value;
请注意,您可以直接通过以下方式在偏特化中更简单地执行此操作:
template <typename T>
struct HasFooWithStringReturnTypeAndIsConst<T,
std::enable_if_t<
std::is_same<std::string,
decltype(std::declval<const T&>().foo(0))
>::value
>> : std::true_type { };
在这里,我们通过在 const T&
上调用它来检查 foo()
是否为 const
,然后简单地检查其 return 类型是否为 std::string
.