2014-05-10 94 views
0

要了解C++ 11的复杂性,我正在玩unique_ptr用iota初始化unique_ptr的容器

我想知道,有没有什么办法可以用iota来初始化一个Container的unique_ptr

我开始与独特-PTR-更少的解决方案,工作正常:

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}); 

这显然会失败。原因:

  • 虽然我与move标记three作为&&这可能不足以复制/移动的初始值到容器中。
  • ++initValue也将无法正常工作,因为initValue的类型为unique_ptr<int>,并且没有定义operator++。但是:我们可以定义一个免费函数unique_ptr<int> operator++(const unique_ptr<int>&);,那至少可以解决这个问题。
  • 但是,复制/移动该操作的结果在unique_ptr中再次不被允许,这一次我看不到如何欺骗编译器使用move

那么,这就是我停下来的地方。我想知道如果我错过了一些有趣的想法,告诉编译器他可能会moveoperator++的结果。或者还有其他障碍吗?

回答

3

为了结束98个unique_ptr的实例,必须有98个调用new。你试图逃脱只有一个 - 这不可能飞。

如果你是在冲击方钉成圆孔真正意图,你可以做something like this

#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; 
} 
+0

我承认,这就像你说的“平方pe成圆洞”,用于学习东西。好的解决方案 – towi

2

也许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); }); 
} 
+0

不错的代码,它比我的理论问题更实用。但我特别想着'iota'。 – towi