[英]How to resolve optional nested type like std::allocator_traits?
An allocator can optionally have nested types like pointer
, const_pointer
. 分配器可以选择具有嵌套类型,如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
. 但是总是可以将这些接口与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.