Ros*_*lav 9 c++ templates c++11 c++14
使用以下方法编写将检测类型中特定成员的存在的模板很容易void_t:
#include <type_traits>
// This comes from cppreference
template<typename... Ts> struct make_void { typedef void type;};
template<typename... Ts> using void_t = typename make_void<Ts...>::type;
// primary template handles types that have no ::aMember 
template< class T, class = void_t<> >
struct has_aMember : std::false_type { };
// specialization recognizes types that do have a ::aMember
template< class T >
struct has_aMember<T, void_t<decltype( T::aMember )>> : std::true_type { };
现在,如果我想检测是否存在其他成员,我将不得不复制粘贴检测器模板,只需更改aMember为otherMember:
template< class T, class = void_t<> >
struct has_otherMember : std::false_type { };
template< class T >
struct has_otherMember<T, void_t<decltype( T::otherMember )>> : std::true_type { };
我想避免这种复制粘贴,并将成员名称作为参数传递给更通用的检测模板版本:
template< class T, class member, class = void_t<> >
struct has_arbitrary_member : std::false_type { };
template< class T, class member >
struct has_arbitrary_member<T, void_t<decltype( T::member )>> : std::true_type { };
所以我可以has_arbitrary_member通过将类型和成员名称作为模板参数传递来使用它:
 std::cout << has_arbitrary_member<MyType, aMember>();
 std::cout << has_arbitrary_member<MyType, otherMember>();
但是,根据我上面草拟的定义,这将无法编译.有没有其他方法来实现这样的功能?
一般情况下,您尝试执行的操作是不可能的,因为除非使用宏修改令牌流,否则无法禁止名称查找aMember.因此,除非您当前在 SFINAE 内,否则您永远无法使用不在范围内的名称,这将抑制错误.
这意味着您确实必须为每个名称编写单独的模板.
这是使用宏并不是一个坏主意的情况之一,尽管这取决于您是否确实需要检查特定名称的成员,或者是否有更好的方法来实现您的目标.
| 归档时间: | 
 | 
| 查看次数: | 396 次 | 
| 最近记录: |