简体   繁体   English

如何解析像std :: allocator_traits这样的可选嵌套类型?

[英]How to resolve optional nested type like std::allocator_traits?

An allocator can optionally have nested types like pointer , const_pointer . 分配器可以选择具有嵌套类型,如pointerconst_pointer But one can always use these interface with std::allocator_traits<Allocator> , which would provide a default version of these types if they are absent in Allocator . 但是总是可以将这些接口与std::allocator_traits<Allocator> ,如果Allocator中没有这些类型,它们将提供这些类型的默认版本。

How is std::allocator_traits implemented? std::allocator_traits是如何实现的? How can a template choose a default version of nested type when it's absent? 如果模板不存在,模板如何选择嵌套类型的默认版本?

The solution is to refer to the type T::pointer in a context where it does not cause an error if it is not a valid type, instead it causes template argument deduction to fail. 解决方案是在上下文中引用类型T::pointer ,如果它不是有效类型,它不会导致错误,而是导致模板参数推断失败。 The general form of this is known as SFINAE, which stands for "Substitution Failure Is Not An Error". 其一般形式称为SFINAE,代表“替换失败不是错误”。 For a explanation of how it works see my SFINAE Functionality Is Not Arcane Esoterica presentation. 有关它如何工作的解释,请参阅我的SFINAE功能不是奥术Esoterica演示文稿。

There are various techniques, often involving overloaded function templates, but my current favourite uses the void_t idiom to select a partial specialization of a class template: 有各种技术,通常涉及重载的函数模板,但我当前的最爱使用void_t惯用法来选择类模板的部分特化:

template<typename T>
  using void_t = void;

template<typename T, typename = void>
  struct get_pointer
  {
    using type = typename T::value_type*;
  };

template<typename T>
  struct get_pointer<T, void_t<typename T::pointer>>
  {
    using type = typename T::pointer;
  };

Now given an allocator type A you can use typename get_pointer<A>::type to refer to A::pointer if that exists, otherwise A::value_type* 现在给定一个分配器类型A你可以使用typename get_pointer<A>::type来引用A::pointer如果存在,否则A::value_type*

The code above works because when A::pointer is a valid type the partial specialization matches and is more specialized than the primary template, and so gets used. 上面的代码有效,因为当A::pointer是有效类型时,部分特化匹配并且比主模板更专业,因此被使用。 When A::pointer is not a valid type the partial specialization is ill-formed, so the primary template is used. A::pointer不是有效类型时,部分特化是不正确的,因此使用主模板。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM