2016-12-27 4 views
1

Как сменить vector<unique_ptr<T>> на vector<unique_ptr<const T>>?конвертировать вектор <unique_ptr <T>> в вектор <unique_ptr <const T>>

Любая минусовая сторона использования reinterpret_cast? Что рекомендуется делать на C++ 11 и вперед?

vector<unique_ptr<const T>> Get() { 
    vector<unique_ptr<T>> some; 
    ... 
    // Any better way to do this? 
    return *(reinterpret_cast<vector<unique_ptr<const T>>*>(&some)); 
} 
+0

Выполняет ли это просто 'return {some.begin(), some.end()}'? –

+0

@BenVoigt: уникальные указатели не могут быть скопированы. –

+0

@ Kerrek: Ах, да. вам понадобится адаптер move-iterator. Тем не менее, перемещение всего существующего 'unique_ptr ' в 'unique_ptr ' в новом векторе является правильным подходом, так как 'reinterpret_cast' является UB. –

ответ

4

Вы можете построить новый вектор, перемещая содержимое старого вектора в него:

#include <iterator> 
#include <memory> 
#include <vector> 

std::vector<std::unique_ptr<T>> v; // ... 

std::vector<std::unique_ptr<const T>> cv(
    std::make_move_iterator(v.begin()), 
    std::make_move_iterator(v.end())); 

reinterpret_cast Ваши предложенные результаты в неопределенном поведении.

Общая тема вашего вопроса заключается в том, что вы пытаетесь найти обработчик управления ресурсами для одной вещи, как если бы это было для другого, связанного с этим. Это проблематичное понятие, поскольку обработчик действительно должен знать, что именно он обрабатывает, и он не имеет смысла. То, что вы действительно хотите сделать, это сообщить вид на , обработанный. В текущем контексте вы можете взять обработанную вещь, указатель T и преобразовать в в указатель const T, используя обычные правила языка, которые работают как ожидалось и избегают говорить об объекте обработчика (уникальный указатель).

+0

[Демонстрация] (https://ideone.com/kOMvYg) –

1

Предполагая, что вы не хотите, чтобы передать в собственность, вы можете создать вектор указателей наблюдателей:

template<class T> 
using const_observer_ptr = const T*; 

template<class T> 
auto Get() { 
    std::vector<const_observer_ptr<T>> some; 

    some.resize(source.size()); 
    std::transform(source.begin(), source.end(), some.begin(), 
        [](auto&& unique) { return unique.get(); }); 
    return some; 
} 

Если вы хотите, чтобы переместить объекты, а затем увидеть другие ответы.

Смежные вопросы