为什么type_identity破坏了is_detected的实现

时间:2018-11-25 08:16:54

标签: c++ c++17 identity template-meta-programming detection-idiom

p0887r1

  

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>();

live demo

  

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没有中断?

0 个答案:

没有答案