2.3基本元功能构建块
类型特征有两个普遍存在的成语:
- 使用给定值定义公共数据成员值
- 定义命名给定类型的公共成员typedef类型
令人惊讶的是,有一个标准实用程序提供了前者(
std::integral_constant
), 但没有提供后者的标准实用程序。type_identity
是此实用程序。这是其他元功能可以构成的基本构建块 简单地继承。例如,remove_const
可以实现如下:template <typename T> struct remove_const : type_identity<T> {}; template <typename T> struct remove_const<T const> : type_identity<T> {};
它的实现很简单:
template<class T>
struct type_identity
{
using type = T;
};
因此,我尝试在我的代码中广泛使用type_identity
,包括Detection Idiom的个人实现:
namespace detail
{
template<class Default,
class AlwaysVoid,
template<class...>
class Op,
class... Args>
struct detector : type_identity<Default> // here
{
using value_t = std::false_type;
};
template<class Default, template<class...> class Op, class... Args>
struct detector<Default, std::void_t<Op<Args...>>, Op, Args...>
: type_identity<Op<Args...>> // here
{
using value_t = std::true_type;
};
} // namespace detail
// ......
在我为my own implementation of is_destructible
使用libcxx的测试套件之前,它在任何地方都可以正常工作,以下是失败的情况:
struct ProtectedDestructor
{
protected:
~ProtectedDestructor()
{}
};
// ......
template<class T>
void
test_is_not_destructible()
{
static_assert(!is_destructible<T>::value, "");
// ......
}
// ......
test_is_not_destructible<ProtectedDestructor>();
prog.cc:83:47:错误:“〜ProtectedDestructor”是“ ProtectedDestructor”的受保护成员
使用has_dtor = decltype(std :: declval()。〜U()); ^ prog.cc:26:19:注意:在此处实例化模板类型别名'has_dtor'
: type_identity<Op<Args...>> ^
prog.cc:45:1:注意:在模板类'detail :: detector的实例化中
......
一旦将type_identity
替换为普通using type = ......
,编译器就没有错误,demo,这是很遗憾的。对于其他琐碎的has_member
检查,type_identity
工作正常,demo。
因此,这里唯一的问题是,对于受保护的dtor,type_identity
将强制结构detail::detector
检查dtor的有效性,而using type = something
则不会。
我认为解决方案很简单,只需删除type_identity
,然后像Walter E. Brown's original implementation一样直接使用using type = something
。但是问题是:
为什么type_idintity
在这里中断而普通的using type = something
没有中断?