c++ - 基于自定义 void_t 实现的成员检测
问题描述
我有这本书 C++ Templates the complete guide,我正在尝试实现一些描述的技术。其中之一是成员函数检测,但我的实现似乎不起作用。
我不能使用 void_t,因为我使用的是 C++11,但我复制了定义,所以这应该不是问题。
以下是代码:
namespace nt_detail
{
template< class... >
using void_t = void;
}
template<typename T, typename = nt_detail::void_t<>>
struct HasHelloMember
: std::false_type {};
template<typename T>
struct HasHelloMember<T,
nt_detail::void_t<decltype(std::declval<T>().hello())>>
: std::true_type {};
这里是测试之一:
class ZZZ
{
};
class ZZZ2
{
public:
void hello()
{}
};
int main()
{
if(HasHelloMember<ZZZ>::value)
{
std::cout << "ZZZ has hello" << std::endl;
}
else
{
std::cout << "ZZZ has NOT hello" << std::endl;
}
if(HasHelloMember<ZZZ2>::value)
{
std::cout << "ZZZ2 has hello" << std::endl;
}
else
{
std::cout << "ZZZ2 has NOT hello" << std::endl;
}
}
在这两种情况下,我都会得到“你好”。我的 void_t 实现可能有问题吗?
解决方案
试试这个void_t
除非你使用的是 C++17 的定义:
template<typename... Ts> struct make_void { typedef void type;};
template<typename... Ts> using void_t = typename make_void<Ts...>::type;
根据https://en.cppreference.com/w/cpp/types/void_t:
在 CWG 1558(一个 C++14 缺陷)之前,别名模板中未使用的参数不能保证确保 SFINAE 并且可以被忽略,因此早期的编译器需要更复杂的 void_t 定义,例如
这是 5.1 版之前的 gcc 问题。
推荐阅读
- c++ - 运行dijkstra算法的问题
- javascript - 如何恢复默认事件侦听器以提交表单
- c - Leetcode:AddressSanitizer 堆缓冲区溢出
- r - 如何在数据框中找到与给定向量最相似的行
- ios - 如果我在 IOS Swift 上有地点坐标信息,我们如何检索 PlaceID
- ios - Google OAuth 登录:iOS 应用程序中的 redirect_uri_mismatch 错误
- html - 无法在最大宽度为 375px 的移动设计上隐藏 SVG 图形的溢出
- python - 为什么使用 __init__(self, **kwargs) 返回以下错误代码:SyntaxError: invalid syntax?
- c++ - strchr函数内的Valgrind memcheck错误
- clojure - 尝试从文本文件中读取数据并填充整数列表