unique_ptr or vector?

后端 未结 5 628
孤城傲影
孤城傲影 2020-12-16 14:23

If you don\'t need dynamic growth and don\'t know the size of the buffer at compile time, when should unique_ptr be used instead of vector<

相关标签:
5条回答
  • 2020-12-16 14:50

    std::vector stores the length of both the size of the variable and the size of the allocated data along with the pointer to the data it's self. std::unique_ptr just stores the pointer so there may be a small gain in using std::unique_ptr.

    No one has yet mentioned the vector provides iterators and function such and size() where as unique ptr does not. So if iterators are needed use std::vector

    0 讨论(0)
  • 2020-12-16 14:51

    Objective Part:

    No, there probably shouldn't be a significant performance difference between the two (though I suppose it depends on the implementation and you should measure if it's critical).

    Subjective Part:

    std::vector is going to give you a well known interface with .size() and .at() and iterators, which will play nicely with all sorts of other code. Using std::unique_ptr gives you a more primitive interface and makes you keep track of details (like the size) separately. Therefore, barring other constraints, I would prefer std::vector.

    0 讨论(0)
  • 2020-12-16 14:56

    There is no performance loss in using std::vector vs. std::unique_ptr<int[]>. The alternatives are not exactly equivalent though, since the vector could be grown and the pointer cannot (this can be and advantage or a disadvantage, did the vector grow by mistake?)

    There are other differences, like the fact that the values will be initialized in the std::vector, but they won't be if you new the array (unless you use value-initialization...).

    At the end of the day, I personally would opt for std::vector<>, but I still code in C++03 without std::unique_ptr.

    0 讨论(0)
  • 2020-12-16 14:57

    If you're in a position where vector<int> is even a possibility, you probably want to go with that except in extreme and rare circumstances. And even then, a custom type instead of unique_ptr<int[]> may well be the best answer.

    So what the heck is unique_ptr<int[]> good for? :-)

    unique_ptr<T[]> really shines in two circumstances:

    1. You need to handle a malloc/free resource from some legacy function and you would like to do it in a modern exception safe style:

    void
    foo()
    {
        std::unique_ptr<char[], void(*)(void*)> p(strdup("some text"), std::free);
        for (unsigned i = 0; p[i]; ++i)
            std::cout << p[i];
        std::cout << '\n';
    }
    

    2. You've need to temporarily secure a new[] resource before transferring it onto another owner:

    class X
    {
        int* data_;
        std::string name_;
    
        static void validate(const std::string& nm);
    public:
        ~X() {delete [] data_;}
    
        X(int* data, const std::string& name_of_data)
            : data_(nullptr),
              name_()
        {
            std::unique_ptr<int[]> hold(data);  // noexcept
            name_ = name_of_data;               // might throw
            validate(name_);                    // might throw
            data_ = hold.release();             // noexcept
        }
    };
    

    In the above scenario, X owns the pointer passed to it, whether or not the constructor succeeds. This particular example assumes a noexcept default constructor for std::string which is not mandated. However:

    1. This point is generalizable to circumstances not involving std::string.
    2. A std::string default constructor that throws is lame.
    0 讨论(0)
  • 2020-12-16 15:01

    C++14 introduces std::dynarray for that purpose.

    Now, between these two constructions :

    1. auto buffer = std::make_unique<int[]>( someCount );
    2. auto buffer = std::vector<int>( someCount, someValue );

    The first gives you an uninitialized array of int but the second initializes it with a value ( 0 if not provide ). So if you do not need the memory to be initialized because you will overwrite it somehow later with something more complex than std::fill, choose 1, if not, choose 2.

    0 讨论(0)
提交回复
热议问题