ИМХО, лучший способ для вашего примера - просто вернуть std::vector
по значению и просто вернуть пустой, если ввод неверен.
std::vector<int> get_vec(int n){
std::vector<int> ret;
for(unsigned i=0; i < n; ++i)
ret.push_back(i);
return ret; // will be empty for (n < 1)
// and will be moved if (n >= 1)
}
Одна вещь, которую вам нужно выучить: вам не нужно явно std::move
, если вы возвращаете локальную переменную. Просто верните по значению. Если копирование возможно, это будет сделано (RVO / NRVO). Если по какой-то причине это невозможно, он сначала попытается удалить его, прежде чем скопировать. Учтите, однако, что член локальной переменной не будет перемещен автоматически, он же
struct object{ std::vector<int> member; };
std::vector<int> foo(){
object o;
// ...
return o.member; // no move, no copy elision, plain old copy
}
Теперь ваша вторая функция также может быть улучшена и уменьшена:
void try_vec(int n){
auto vec = get_vec(n); // will elide copy or simply move
for(auto& x : vec) // will not loop if vector is empty
std::cout << x << ' '; // why space and newline?
std::cout << "\n"; // don't use std::endl, it also flushes the stream
}
А из вашей исходной функции:
vec->clear(); //clear vector
vec.reset(nullptr);
Не требуется, в этом вся причина умных указателей и контейнеров управления ресурсами. Они уничтожат то, что им принадлежит, когда они выйдут за рамки.