基于自定义 void_t 实现的成员检测
Member detection based on custom void_t implementation
我已经拿到了 C++ 模板完整指南一书,我正在尝试实现其中描述的一些技术。其中之一是成员函数检测,但我的实现似乎不起作用。
我不能使用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;
}
}
在这两种情况下我都得到 "has hello"。也许我的 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:
Until CWG 1558 (a C++14 defect), unused parameters in alias templates
were not guaranteed to ensure SFINAE and could be ignored, so earlier
compilers require a more complex definition of void_t, such as
这是 gcc 5.1 版之前的问题。
我已经拿到了 C++ 模板完整指南一书,我正在尝试实现其中描述的一些技术。其中之一是成员函数检测,但我的实现似乎不起作用。
我不能使用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;
}
}
在这两种情况下我都得到 "has hello"。也许我的 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:
Until CWG 1558 (a C++14 defect), unused parameters in alias templates were not guaranteed to ensure SFINAE and could be ignored, so earlier compilers require a more complex definition of void_t, such as
这是 gcc 5.1 版之前的问题。