检查类是否具有函数(返回类型和常量选中)
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
已经返回 true,因此工作正常(。 这是我所拥有的:
#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!)
}
有人可以解释为什么他们返回true
而不是false
吗? 如何修复它们以使它们返回 false? A::foo(int)
是一个返回布尔值的 const 函数,所以它们应该返回 false,不是吗?
您的支票适用于:
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
,然后简单地检查它的返回类型是否为 std::string
。
相关文章:
- 如何获取std::result_of函数的返回类型
- 奇怪的结构&GCC&clang(void*返回类型)
- 如何建立使用模板函数的lambda函数的尾部返回类型
- 为什么与常规GCC不同,即使有"学究性错误",MinGW-GCC也能容忍丢失的返回类型
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 为什么作为返回类型的右值引用不能初始化非常量引用?
- 为什么类的赋值运算符的返回类型通常是非常量(而不是常量)引用?
- 如何在另一个成员函数中修改具有常量返回类型的成员函数的返回值
- 从函数返回类型中删除常量是否会中断 ABI
- 模板引用折叠正在删除常量引用返回类型的cv限定符
- 返回常量模板类型的模板函数
- 重载运算符:常量与非常量返回类型:任何性能差异
- 常量返回类型在 NRVO 案例中的相关性
- 常量字符* 返回类型
- 函数常量返回类型:类型引用的初始化无效
- 与返回类型(引用、常量引用)混淆
- 使用常量引用作为返回类型
- C++方法的区别仅在于返回类型(和常量)的"恒常性"
- 检查类是否具有函数(返回类型和常量选中)
- 后缀自增运算符的常量返回类型