Are there any cases where it is incorrect to replace push_back with emplace_back?

前端 未结 6 1471
不思量自难忘°
不思量自难忘° 2021-01-02 09:44

Can I break a valid C++03 program by replacing std::vector::push_back with emplace_back and compiling it with C++ 11 compiler? From reading e

6条回答
  •  我在风中等你
    2021-01-02 10:22

    The emplace versions don't create an object of the desired type at all under exception circumstances. This can lead to a bug.

    Consider the following example, which uses std::vector for simplicity (assume uptr behaves like std::unique_ptr, except the constructor is not explicit):

    std::vector> vec;
    vec.push_back(new T());
    

    It is exception-safe. A temporary uptr is created to pass to push_back, which is moved into the vector. If reallocation of the vector fails, the allocated T is still owned by a smart pointer which correctly deletes it.

    Compare to:

    std::vector> vec;
    vec.emplace_back(new T());
    

    emplace_back is not allowed to create a temporary object. The ptr will be created once, in-place in the vector. If reallocation fails, there is no location for in-place creation, and no smart pointer will ever be created. The T will be leaked.

    Of course, the best alternative is:

    std::vector> vec;
    vec.push_back(make_unique());
    

    which is equivalent to the first, but makes the smart pointer creation explicit.

提交回复
热议问题