Can I list-initialize a vector of move-only type?

前端 未结 5 1120
感情败类
感情败类 2020-11-22 08:30

If I pass the following code through my GCC 4.7 snapshot, it tries to copy the unique_ptrs into the vector.

#include 
#include <         


        
5条回答
  •  遥遥无期
    2020-11-22 08:48

    Using Johannes Schaub's trick of std::make_move_iterator() with std::experimental::make_array(), you can use a helper function:

    #include 
    #include 
    #include 
    #include 
    
    struct X {};
    
    template
    auto make_vector( std::array&& a )
        -> std::vector
    {
        return { std::make_move_iterator(std::begin(a)), std::make_move_iterator(std::end(a)) };
    }
    
    template
    auto make_vector( T&& ... t )
        -> std::vector::type>
    {
        return make_vector( std::experimental::make_array( std::forward(t)... ) );
    }
    
    int main()
    {
        using UX = std::unique_ptr;
        const auto a  = std::experimental::make_array( UX{}, UX{}, UX{} ); // Ok
        const auto v0 = make_vector( UX{}, UX{}, UX{} );                   // Ok
        //const auto v1 = std::vector< UX >{ UX{}, UX{}, UX{} };           // !! Error !!
    }
    

    See it live on Coliru.

    Perhaps someone can leverage std::make_array()'s trickery to allow make_vector() to do its thing directly, but I did not see how (more accurately, I tried what I thought should work, failed, and moved on). In any case, the compiler should be able to inline the array to vector transformation, as Clang does with O2 on GodBolt.

提交回复
热议问题