2014-05-10 129 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