在 SFINAE 上下文中编写
allocator_traits<T>::value_type
似乎是测试类型 T
是否实际上是分配器的可行方法。然而,这并不是特别优雅,而且我过去也曾被极端情况所困扰。
因此我的问题是:在 T 是分配器的情况下,如何最好地实现包含
is_allocator<T>
true 的 ::value
特征,否则 ::false?
在 SFINAE 上下文中编写
似乎是测试类型allocator_traits<T>::value_type
是否实际上是分配器的可行方法。T
我认为这还不够。这只会检查
T
是否有 value_type
并且可重新绑定。 libstdc++ 和 libc++ 都会将 std::map<int, int>
视为该模型中的分配器。
该标准有要求表,说明什么构成
Allocator
。我认为你最好的选择就是检查几个表达式的有效性,即:
X::value_type
a.allocate(n)
有效并返回 X::pointer
a.deallocate(p, n)
有效(其中
X
是您要检查的类型,a
是 X&
,n
是 allocator_traits<X>::size_type
类型的值)
如果有一种类型检查了所有这些框,但仍然不是 allcoator,那么... ́\_(ツ)_/́。
为了完整起见,这里是 @Barry 答案的 C++20 概念:
template <typename Allocator>
concept is_allocator = requires(Allocator a, typename Allocator::value_type* p) {
{ a.allocate(0) } -> std::same_as<decltype(p)>;
{ a.deallocate(p, 0) } -> std::same_as<void>;
};
template<typename Allocator>
concept is_allocator = requires(Allocator a, typename ::std::allocator_traits<Allocator>::value_type* p) {
{
a.allocate(0)
} -> std::same_as<decltype(p)>;
{
a.deallocate(p, 0)
} -> std::same_as<void>;
};
为了匹配巴里的答案,它看起来像这样,有一个非常微小的差异,因为某些类型将具有一个将传递前者但不会传递后者的 value_type。