首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不推荐使用std::allocator<void>

不推荐使用std::allocator<void>
EN

Stack Overflow用户
提问于 2018-05-09 10:42:11
回答 2查看 2.5K关注 0票数 15

相关:Why do standard containers require allocator_type::value_type to be the element type?

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

代码语言:javascript
复制
template<>
struct allocator<void>;

我想知道它是否因为主模板现在能够支持allocator<void>而被弃用,或者allocator<void>的用例已被弃用。

如果是后者,我想知道为什么。我认为allocator<void>在指定未绑定到特定类型(所以只是一些模式/元数据)的分配器时很有用。

EN

回答 2

Stack Overflow用户

发布于 2018-05-09 15:51:15

根据p0174r0的说法

类似地,std::allocator<void>的定义使得各种模板重新绑定技巧可以在原始的C++98库中工作,但它不是一个实际的分配器,因为它同时缺少allocatedeallocate成员函数,这两个函数在默认情况下不能从allocator_traits合成。随着C++11和allocator_traits中的void_pointerconst_void_pointer类型别名的出现,这种需求消失了。但是,我们继续指定它,以避免破坏尚未升级到支持每个C++11的通用分配器的旧代码。

票数 3
EN

Stack Overflow用户

发布于 2019-01-08 21:42:06

这并不是说std::allocator<void>被弃用了,只是它不是一个显式的专门化。

它过去的样子是这样的:

代码语言:javascript
复制
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&.
}

现在,由于std::allocator<T>::referencestd::allocator<T>::const_reference已被弃用,因此不需要对void进行显式专门化。您可以只使用std::allocator<void>std::allocator_traits<std::allocator<void>>::template rebind<U>来获取std::allocator<U>,但不能实例化std::allocator<void>::allocates

例如:

代码语言:javascript
复制
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);
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50244772

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档