Is it safe to move elements of a initializer list?

2019-01-28 03:16发布

问题:

Possible Duplicate:
initializer_list and move semantics

In this code:

#include <vector>
#include <initializer_list>

template<typename T>
class some_custom_container : public std::vector<T>
{
public:
   some_custom_container(const std::initializer_list<T>& contents)
   {
      for (auto& i : contents)
        this->emplace_back(std::move(i));
   }
};

class test_class
{};

int main()
{
    test_class a;

    some_custom_container<test_class> i = { a, test_class(), a };
}

If I've understand it, all objects in { a, test_class(), a } are safe-constructed: the named-objects are copied and the unnamed objects are moved to construct the initializer_list. After, this initializer_list is passed by reference to the some_custom_container's constructor.

Then, to avoid useless doble-copies I move all of them to fill the vector.

Is it safe this constructor? I mean, in a strange situation, for example if T is evaluated as a reference & or &&, is the vector always well-filled (contains it safe objects)?

If this is the case, why the initializer_list constructor implementations of stl containers aren't implemented in this way? As I know, their constructors copy and don't move the contents.

回答1:

initializer_list only provides const access to its elements. You could use const_cast to make that code compile, but then the moves might end up with undefined behaviour (if the elements of the initializer_list are truly const). So, no it is not safe to do this moving. There are workarounds for this, if you truly need it.