Чтобы узнать о тонкостях C ++ 11, я играю в unique_ptr
немного.
Интересно, есть ли способ использовать iota
инициализировать контейнер unique_ptr
?
Я начал с решения «unique-ptr-less», которое отлично работает:
std::vector<int> nums(98); // 98 x 0
std::iota(begin(nums), end(alleZahlen), 3); // 3..100
Теперь давайте сделаем это, насколько мы можем использовать unique_ptr
std::vector<std::unique_ptr<int>> nums(98); // 98 x nullptr
std::unique_ptr three{ new int{3} };
std::iota(begin(nums), end(nums), std::move{three});
Это не удается, очевидно. Причины:
three
с move
как &&
этого может быть недостаточно для копирования / перемещения начального значения в контейнер.++initValue
тоже не сработает, потому что initValue
имеет тип unique_ptr<int>
и нет operator++
определены. Но: мы могли бы определить свободную функцию unique_ptr<int> operator++(const unique_ptr<int>&);
и это позаботится об этом по крайней мере.unique_ptr
и на этот раз я не могу понять, как я мог обмануть компилятор в использовании move
,Ну, вот где я остановился. И мне интересно, если я пропустил какую-то интересную идею о том, как сказать компилятору, что он может move
результаты operator++
, Или есть и другие препятствия?
Для того чтобы в итоге 98 экземпляров unique_ptr
должно быть 98 звонков new
, Вы пытаетесь сойти с рук только с одним — который не может летать.
Если вы действительно хотите вбить квадратный колышек в круглое отверстие, вы можете сделать что-то вроде этого:
#include <algorithm>
#include <iostream>
#include <memory>
#include <vector>
class MakeIntPtr {
public:
explicit MakeIntPtr(int v) : value_(v) {}
operator std::unique_ptr<int>() {
return std::unique_ptr<int>(new int(value_));
}
MakeIntPtr& operator++() { ++value_; return *this; }
private:
int value_;
};
int main() {
std::vector<std::unique_ptr<int>> nums(98);
std::iota(begin(nums), end(nums), MakeIntPtr(3));
std::cout << *nums[0] << ' ' << *nums[1] << ' ' << *nums[2];
return 0;
}
Может быть std::generate_n
лучший алгоритм для этого?
std::vector<std::unique_ptr<int>> v;
{
v.reserve(98);
int n = 2;
std::generate_n(std::back_inserter(v), 98,
[&n]() { return std::make_unique<int>(++n); });
}