Учитывая тип, который не копируемый, но подвижный, я пытаюсь создать boost::ptr_vector
этого типа и вернуть его из функции. Я использую Visual Studio 2013.
struct NonCopyableButMovable
{
using this_type = NonCopyableButMovable;
this_type() {}
this_type(this_type const &) = delete;
this_type & operator =(this_type const &) = delete;
this_type(this_type &&) {} // no default move ctr in VS2013
this_type & operator =(this_type &&) {} // no default move assignment in VS2013
};
boost::ptr_vector<NonCopyableButMovable> make_ptr_vector()
{
boost::ptr_vector<NonCopyableButMovable> res;
//return res; // (1)
//return std::move(res); // (2)
return boost::ptr_vector<NonCopyableButMovable>(); // (3)
}
Я могу только получить (3) для компиляции: временный ptr_vector
перемещается. С помощью (1) и (2) компилятор вызывает boost::new_clone
который пытается позвонить NonCopyableButMovable
Копируй конструктор.
В соответствии с этот FAQ ответ, раздел «Выход из функций», (1) должен работать, т.е. res
должны быть перемещены, а не скопированы.
В соответствии с эта тема, (2) может использоваться в качестве обходного пути для компиляторов, которые не полностью соответствуют стандарту, но по причине, которую я не понимаю, boost::new_clone
также вызывается с помощью (2).
Обратите внимание, что если я заменю boost::ptr_vector
с std::vector
, три способа возврата компиляции нормально.
Что-то не так в семантике ходов Boost ptr_containers с VS2013? Что происходит в случае (2)? Каким будет обходной путь для реализации такой фабричной функции ptr_container?
Задача ещё не решена.
Других решений пока нет …