可能吗? std :: vector <double> my_vec(sz);已分配但未初始化或已填写

时间:2016-12-08 21:30:37

标签: c++ c++11 vector stl

在[Value-Initialized Objects in C++11 and std::vector constructor,Channel72问,

问题:我的理解是否正确?如果T是POD,显式std :: vector(size_type count)是否提供未初始化的数组(类似于malloc)?

答案是否定的。

我的问题是,&#34;好的,那是什么?&#34;

Nevin的回应之一暗示回答我的问题。为了澄清,我的问题是,有没有办法使用std :: vector&lt; double&gt;没有它无偿地用零或其他任何东西填充分配的内存?

我不是要求解决方法,比如以零大小启动向量并使用push_back()。这并不总是可行的,此外,在这一点上,我想让它理所当然,除了我想让它弄明白外。

我不能得到Nevin的建议,一个自定义分配器,来编译。 VC ++ 2017rc(Dinkum)以其通常难以理解的方式抱怨。关于std :: _ Wrap_alloc的东西。 Nevin的代码不完整,我可能不知道如何完成它。在我看到他之前,我编写了自己的自定义分配器,这似乎有效,但我对自己的理解不够自信,不会发誓。

在我为此困惑的时候,我本可以为std :: vector编写一个较少教条的替代品,加上伟大的美国小说的几个章节。

3 个答案:

答案 0 :(得分:5)

HOORAY!理查德克里滕救援!他在这个问题上的评论直接导致答案。

零喷射罪魁祸首是默认的分配器模板,即std :: allocator。所以我们替换它,或用分配器适配器修改它。

我整理了一些代码,并扩展了评论。比尔,请随时发布更全面的答案。但是下面的方法非常好。

// Allocator adapter
// Given an allocator A, (std::allocator by default), this adapter 
// will, when feasible, override A::construct() with a version that 
// employs default construction rather than value-initialization.
// "Feasible" means the object (U *ptr) is default-constructable and
// the default constructor cannot throw exceptions.
// 
// Thus it thwarts gratuitous initializations to zeros or whatever.

template <typename T, typename A = std::allocator<T>>
class default_init_allocator : public A {
    typedef std::allocator_traits<A> a_t;
public:
    // http://en.cppreference.com/w/cpp/language/using_declaration
    using A::A; // Inherit constructors from A

    template <typename U> struct rebind {
        using other =
            default_init_allocator
            <  U, typename a_t::template rebind_alloc<U>  >;
    };

    template <typename U>
    void construct(U* ptr)
        noexcept(std::is_nothrow_default_constructible<U>::value) {
        ::new(static_cast<void*>(ptr)) U;
    }

    template <typename U, typename...Args>
    void construct(U* ptr, Args&&... args) {
        a_t::construct(static_cast<A&>(*this),
            ptr, std::forward<Args>(args)...);
    }
};

答案 1 :(得分:0)

没有试过这个,但是从一些谷歌搜索似乎可以通过向std :: vector提供自定义分配器来实现。见最后一行 https://en.cppreference.com/w/cpp/named_req/DefaultInsertable

  

如果不希望进行值初始化,例如,如果对象是非类型类型并且不需要清零,则可以通过提供自定义Allocator :: construct

来避免它。

答案 2 :(得分:-4)

您可以使用具有已分配内存的数组初始化向量。

Type* typeArray = new Type [size];
vector <Type> typeVec (typeArray, typeArray+size);

这会给你分配的内存(虽然它会很垃圾)但你必须小心访问它,因为它可以让你调用     typeVec [n] .typeVal 并且它可能会产生未定义的行为,除非你实际初始化了n

的值

或者如果Type是非类型类型,那么n处的值只是剩下的值的值