我有一个具有std::vector<std::unique_ptr<T>>
的类,我想在std::unique_ptr
持有的指针引用上创建一个迭代器。
#include <iostream>
#include <vector>
#include <memory>
#include <algorithm>
class Pointer
{
public:
Pointer() {}
~Pointer() {}
void printSomething()
{
std::cout << "Hi" << std::endl;
}
};
class Keeper
{
public:
typedef std::vector<std::unique_ptr<Pointer>> vector_type;
Keeper() {}
virtual ~Keeper() {}
void push_back(vector_type::value_type pointer)
{
data.push_back(pointer);
}
vector_type::const_iterator begin() const
{
return data.begin();
}
vector_type::const_iterator end() const
{
return data.end();
}
private:
vector_type data;
};
int main()
{
Keeper keeper;
keeper.push_back(std::make_unique<Pointer>());
std::for_each(keeper.begin(), keeper.end(), [] (auto pointer) {
pointer.printSomething();
});
}
我遇到了一连串错误,我无法放在这里......
如何提供通过std::unique_ptr
的参考进行交互的界面?
答案 0 :(得分:1)
您的代码需要进行一些更改。
#include<type_traits>
class Keeper
{
//...
public:
void push_back(value_type&& pointer)
{
data.push_back(std::move(pointer)); //(1)
}
//...
};
int main()
{
// ...
std::for_each(keeper.begin(), keeper.end(), [] (auto const& pointer) { //(2)
pointer->printSomething(); //(3)
});
}
(1)将unique_ptr
通过右值引用并将move
传递到向量中。这是必要的,因为您无法复制unique_ptr
,但只应用移动。或者更好,您可以使用emplace_back
并简单地传递构造函数参数
template<typename ... Args>
void emplace_back(Args&& ... args)
{
data.emplace_back(std::forward<Args>(args) ...);
}
请注意,之前的调用等同于以下内容,因为编译器进行了隐式转换:
data.emplace_back(std::unique_ptr<Pointer>(std::forward<Args>(args) ...));
(2)通过引用传递向量的元素。同样,这是必要的,因为您无法通过值传递它们,这意味着副本。
(3)由于它是一个指针,您必须通过->
取消引用传递的元素。
答案 1 :(得分:0)
实际上,此问题的解决方案已在Boost.Iterator中实现。它很性感:
std::vector<std::unique_ptr<int>> vec;
// [..]
using iterator = boost::indirect_iterator<decltype(vec)::iterator>;
iterator iter = vec.begin(),
end = vec.end();
indirect_iterator
可以在<boost/iterator/indirect_iterator.hpp>
中找到
可以使用如下:
while (iter != end)
std::cout << *iter++ << ", ";