如何解决可选的嵌套类型像std :: allocator_traits? [英] How to resolve optional nested type like std::allocator_traits?

查看:524
本文介绍了如何解决可选的嵌套类型像std :: allocator_traits?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

分配器可以可选地具有嵌套类型,例如 pointer const_pointer 。但是总是可以使用 std :: allocator_traits< Allocator> 这些接口来提供这些类型的默认版本,如果它们不在 Allocator



如何实现 std :: allocator_traits 如果模板缺少,模板如何选择默认版本的嵌套类型?

解决方案

解决方案是引用< c $ c> T :: pointer 在上下文中,如果它不是有效的类型,它不会导致错误,而是导致模板参数的扣除失败。其一般形式被称为SFINAE,其代表替换失败不是错误。有关其工作原理的解释,请参阅我的 SFINAE功能不是奥秘Esoterica 演示文稿。 p>

有各种技术,通常涉及重载的函数模板,但我当前的喜欢使用 void_t idiom选择部分专业化类模板:

  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;
};

现在给定一个分配器类型 A 使用 typename get_pointer< A> :: type 引用 A :: pointer $ c> A :: value_type *



上述代码起作用,因为当 A :: pointer 是部分专门化匹配的有效类型,比主模板更专业,因此被使用。当 A :: pointer 不是有效类型时,部分专业化不成型,因此使用主模板。


An allocator can optionally have nested types like pointer, const_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.

How is std::allocator_traits implemented? 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. The general form of this is known as SFINAE, which stands for "Substitution Failure Is Not An Error". For a explanation of how it works see my SFINAE Functionality Is Not Arcane Esoterica presentation.

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:

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*

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. When A::pointer is not a valid type the partial specialization is ill-formed, so the primary template is used.

这篇关于如何解决可选的嵌套类型像std :: allocator_traits?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆