简体   繁体   English

unique_ptr <int []>或vector <int>?

[英]unique_ptr<int[]> or vector<int>?

If you don't need dynamic growth and don't know the size of the buffer at compile time, when should unique_ptr<int[]> be used instead of vector<int> if at all? 如果您不需要动态增长并且在编译时不知道缓冲区的大小,那么应该使用unique_ptr<int[]>而不是vector<int>如果有的话)?

Is there a significant performance loss in using vector instead of unique_ptr ? 使用vector而不是unique_ptr会有明显的性能损失吗?

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. 如果你处于vector<int>甚至可能的位置,你可能想要除了在极端和罕见的情况下使用它。 And even then, a custom type instead of unique_ptr<int[]> may well be the best answer. 即便如此,自定义类型而不是unique_ptr<int[]>可能是最好的答案。

So what the heck is unique_ptr<int[]> good for? 那么unique_ptr<int[]>好处是什么? :-) :-)

unique_ptr<T[]> really shines in two circumstances: unique_ptr<T[]>在两种情况下真的很棒:

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: 1.您需要处理来自某些遗留函数的malloc / free资源,并且您希望以现代异常安全样式执行此操作:

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: 2.在将新[]资源转移到另一个所有者之前,您需要临时保护它:

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. 在上面的场景中, X拥有传递给它的指针,无论构造函数是否成功。 This particular example assumes a noexcept default constructor for std::string which is not mandated. 此特定示例假定std::stringnoexcept默认构造函数,该构造函数未强制执行。 However: 然而:

  1. This point is generalizable to circumstances not involving std::string . 这一点可以推广到不涉及std::string
  2. A std::string default constructor that throws is lame. 抛出的std::string默认构造函数是蹩脚的。

There is no performance loss in using std::vector vs. std::unique_ptr<int[]> . 使用std::vectorstd::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 ...). 还有其他差异,比如值将在std::vector初始化,但如果你new数组它们将不会出现(除非你使用值初始化 ......)。

At the end of the day, I personally would opt for std::vector<> , but I still code in C++03 without std::unique_ptr . 在一天结束时,我个人会选择std::vector<> ,但我仍然在没有std::unique_ptr C ++ 03中编码。

C++14 introduces std::dynarray for that purpose. 为此,C ++ 14引入了std :: dynarray。

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 ). 第一个给你一个未初始化的int数组,但第二个用一个值初始化它(如果不提供,则为0)。 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. 因此,如果你不需要初始化内存,因为稍后会用比std::fill更复杂的东西覆盖它,选择1,如果不是,则选择2。

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::vector存储变量大小和分配数据大小的长度以及指向自身数据的指针。 std::unique_ptr just stores the pointer so there may be a small gain in using std::unique_ptr . std::unique_ptr只存储指针,因此使用std::unique_ptr可能会有一点小小的好处。

No one has yet mentioned the vector provides iterators and function such and size() where as unique ptr does not. 还没有人提到过向量提供迭代器和函数这样的和size() ,其中唯一的ptr没有。 So if iterators are needed use std::vector 因此,如果需要迭代器,请使用std::vector

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. std::vector将为您提供一个与.size().at()以及迭代器的众所周知的接口,它可以很好地与各种其他代码一起使用。 Using std::unique_ptr gives you a more primitive interface and makes you keep track of details (like the size) separately. 使用std::unique_ptr为您提供了更原始的界面,使您可以分别跟踪详细信息(如大小)。 Therefore, barring other constraints, I would prefer std::vector . 因此,除了其他约束,我更喜欢std::vector

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM