C++ std::分配器的弃用<;无效>;

C++ std::分配器的弃用<;无效>;,c++,memory-management,c++17,c++-standard-library,allocator,C++,Memory Management,C++17,C++ Standard Library,Allocator,相关的: 据说自C++17以来,以下内容已被弃用: template<> struct allocator<void>; 模板 结构分配器; 我想知道它是否已被弃用,因为现在仅主模板就可以容纳分配器,还是分配器的用例已被弃用 如果是后者,我想知道为什么。我认为allocator在指定未绑定到特定类型的分配器时非常有用(因此只需一些模式/元数据)。根据 类似地,定义了std::allocator,以便各种模板 重新绑定技巧可以在原来的C++98库中工作,但事实上确实如此

相关的:

据说自C++17以来,以下内容已被弃用:

template<>
struct allocator<void>;
模板
结构分配器;
我想知道它是否已被弃用,因为现在仅主模板就可以容纳
分配器
,还是
分配器
的用例已被弃用

如果是后者,我想知道为什么。我认为
allocator
在指定未绑定到特定类型的分配器时非常有用(因此只需一些模式/元数据)。

根据

类似地,定义了
std::allocator
,以便各种模板 重新绑定技巧可以在原来的C++98库中工作,但事实上确实如此 不是实际的分配器,因为它同时缺少
allocate
deallocate
成员函数,默认情况下不能从
分配器特性
。这种需求随着C++11和
void\u指针的出现而消失
和
const\u void\u指针
在分配器中键入别名。然而,我们 继续指定它,以避免破坏已删除的旧代码 根据C++11,尚未升级到支持通用分配器


并不是说
std::allocator
不受欢迎,只是它不是一个明确的专业化

它过去的样子是这样的:

template<class T>
struct allocator {
    typedef T value_type;
    typedef T* pointer;
    typedef const T* const_pointer;
    // These would be an error if T is void, as you can't have a void reference
    typedef T& reference;
    typedef const T& const_reference;

    template<class U>
    struct rebind {
        typedef allocator<U> other;
    }

    // Along with other stuff, like size_type, difference_type, allocate, deallocate, etc.
}

template<>
struct allocator<void> {
    typedef void value_type;
    typedef void* pointer;
    typedef const void* const_pointer;

    template<class U>
    struct rebind {
        typdef allocator<U> other;
    }
    // That's it. Nothing else.
    // No error for having a void&, since there is no void&.
}

这里有一个讨论。试图ping@Nicolabolas谁参加了讨论,这个问题对我来说也相当有趣。相关:。
template<class Alloc = std::allocator<void>>
class my_class;  // allowed

int main() {
    using void_allocator = std::allocator<void>;
    using void_allocator_traits = std::allocator_traits<void_allocator>;
    using char_allocator = void_allocator_traits::template rebind_alloc<char>;
    static_assert(std::is_same<char_allocator, std::allocator<char>>::value, "Always works");

    // This is allowed
    void_allocator alloc;

    // These are not. Taking the address of the function or calling it
    // implicitly instantiates it, which means that sizeof(void) has
    // to be evaluated, which is undefined.
    void* (void_allocator::* allocate_mfun)(std::size_t) = &void_allocator::allocate;
    void_allocator_traits::allocate(alloc, 1);  // calls:
    alloc.allocate(1);
}