Обновление для C ++ 20: используя трюк Йоханнеса Шауба std::make_move_iterator()
с std::to_array()
C ++ 20, вы можете использовать вспомогательную функцию, такую как make_tuple()
и т. д., здесь она называется make_vector()
:
#include <array>
#include <memory>
#include <vector>
struct X {};
template<class T, std::size_t N>
auto make_vector( std::array<T,N>&& a )
-> std::vector<T>
{
return { std::make_move_iterator(std::begin(a)), std::make_move_iterator(std::end(a)) };
}
template<class... T>
auto make_vector( T&& ... t )
{
return make_vector( std::to_array({ std::forward<T>(t)... }) );
}
int main()
{
using UX = std::unique_ptr<X>;
const auto a = std::to_array({ UX{}, UX{}, UX{} }); // Ok
const auto v0 = make_vector( UX{}, UX{}, UX{} ); // Ok
//const auto v2 = std::vector< UX >{ UX{}, UX{}, UX{} }; // !! Error !!
}
Смотрите в прямом эфире на Godbolt.
Аналогичный ответ для более старого C ++:
Используя уловку Йоханнеса Шауба std::make_move_iterator()
с std::experimental::make_array()
, вы можете использовать вспомогательную функцию:
#include <memory>
#include <type_traits>
#include <vector>
#include <experimental/array>
struct X {};
template<class T, std::size_t N>
auto make_vector( std::array<T,N>&& a )
-> std::vector<T>
{
return { std::make_move_iterator(std::begin(a)), std::make_move_iterator(std::end(a)) };
}
template<class... T>
auto make_vector( T&& ... t )
-> std::vector<typename std::common_type<T...>::type>
{
return make_vector( std::experimental::make_array( std::forward<T>(t)... ) );
}
int main()
{
using UX = std::unique_ptr<X>;
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 !!
}
Смотрите в прямом эфире на Coliru.
Возможно, кто-то сможет использовать уловку std::make_array()
, чтобы позволить make_vector()
делать свое дело напрямую, но я не видел как (точнее, я пробовал то, что, по моему мнению, должно работать, потерпел неудачу и двинулся дальше). В любом случае компилятор должен иметь возможность встроить массив в векторное преобразование, как это делает Clang с O2 на GodBolt.
person
metal
schedule
20.03.2017