测试类型是否是分配器的正确方法是什么?

问题描述 投票:0回答:3

在 SFINAE 上下文中编写

allocator_traits<T>::value_type
似乎是测试类型
T
是否实际上是分配器的可行方法。然而,这并不是特别优雅,而且我过去也曾被极端情况所困扰。

因此我的问题是:在 T 是分配器的情况下,如何最好地实现包含

is_allocator<T>
true 的
::value
特征,否则 ::false?

c++ c++14 type-traits allocator
3个回答
6
投票

在 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,那么... ́\_(ツ)_/́。


1
投票

为了完整起见,这里是 @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>;
};

实例


0
投票
    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。

© www.soinside.com 2019 - 2024. All rights reserved.