Инициализируйте контейнер unique_ptr с помощью йоты

Чтобы узнать о тонкостях 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++, Или есть и другие препятствия?

0

Решение

Для того чтобы в итоге 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;
}
3

Другие решения

Может быть 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); });
}
2

По вопросам рекламы [email protected]