C++ C+中唯一的_ptr向量+;11

C++ C+中唯一的_ptr向量+;11,c++,c++11,unique-ptr,C++,C++11,Unique Ptr,我最近切换到了C++11,我正在努力适应那里的良好实践。 我经常遇到的情况是: class Owner { private: vector<unique_ptr<HeavyResource>> _vectorOfHeavyResources; public: virtual const vector<const HeavyResource*>* GetVectorOfResources() const; }; 类所有者 { 私人: 向量_重资

我最近切换到了C++11,我正在努力适应那里的良好实践。 我经常遇到的情况是:

class Owner
{
private:
    vector<unique_ptr<HeavyResource>> _vectorOfHeavyResources;
public:
    virtual const vector<const HeavyResource*>* GetVectorOfResources() const;
};
类所有者
{
私人:
向量_重资源向量;
公众:
虚拟常量向量*GetVectorOfResources()常量;
};
这需要我做一些事情,比如添加一个_returnableVector并翻译源向量,以便以后能够返回它:

_returnableVector = vector<HeavyResource*>;
for (int i=0; i< _vectorOfHeavyResources.size(); i++)
{
    _returnableVector.push_back(_vectorOfHeavyResources[i].get());
}
\u returnableVector=vector;
对于(int i=0;i<_vectorOfHeavyResources.size();i++)
{
_returnableVector.push_back(_vectorOfHeavyResources[i].get());
}
有没有人注意到类似的问题?你的想法和解决方案是什么?我在这里得到了所有人的想法吗

更新: 还有一件事: 如果一个类将某个处理的结果返回为
vector
(它将结果的所有权传递给调用者),并且应该用于某些后续处理,该怎么办

vector<unique_ptr<HeavyResource>> partialResult = _processor1.Process();
// translation
auto result = _processor2.Process(translatedPartialResult); // the argument of process is vector<const HeavyResource*>
vector partialResult=_processor1.Process();
//翻译
自动结果=_processor2.Process(translatedPartialResult);//过程的参数是向量

我建议您提供直接访问元素的函数,而不是维护和返回un-
唯一的\u ptr
ed向量。这封装了资源的存储;客户端不知道它们存储为
unique_ptr
s,也不知道它们保存在
向量中

一种可能是使用
boost::indirect_iterator
自动取消引用您的
unique_ptr

using ResourceIterator =
     boost::indirect_iterator<std::vector<std::unique_ptr<HeavyResource>>::iterator,
                              const HeavyResource>;
ResourceIterator begin() { return std::begin(_vectorOfHeavyResources); }
ResourceIterator end() { return std::end(_vectorOfHeavyResources); }
使用ResourceIterator=
boost::间接迭代器;
ResourceIterator begin(){return std::begin(_vectorOfHeavyResources);}
ResourceIterator end(){return std::end(_vectorOfHeavyResources);}

你可能想考虑<代码> SydDypPT/<代码>,因为它可能反映了你想要达到的目标。您可能希望在较小的范围内使用

unique\u ptr
,或者任何时候您希望使用对象只反映一件事情。

我尝试了以下方法:

public:
   const std::vector<int const *> getResource()
   {
       return reinterpret_cast<std::vector<const int *> &>(resources);
   }

private:
   std::vector<unique_ptr<int>> resources;
公共:
const std::vector getResource()
{
返回重新解释(资源);
}
私人:
病媒资源;

它起作用了。

如果您经常遇到这种情况,那么编写一个类可能是有意义的,它的行为类似于一个唯一的ptr,但将指针的常量传递给它所指向的对象。这样,您就可以返回对向量的常量引用

最后我写了一次,就这样结束了:

#include <iostream>
#include <vector>
#include <memory>

//unique,const-preserving pointer
template<class T>
class ucp_ptr {
    std::unique_ptr<T> ptr;
public:
    ucp_ptr() = default;
    ucp_ptr(T* ptr) :ptr{ ptr }{};
    ucp_ptr(std::unique_ptr<T>&& other) :ptr(std::move(other)){};

    T&        operator*()       { return ptr.get(); }
    T const & operator*()const  { return ptr.get(); }

    T*        operator->()      { return ptr.get(); }
    T const * operator->()const { return ptr.get(); }
};

struct Foo {
    int a = 0;
};

int main() {
    std::vector<ucp_ptr<Foo>> v;
    v.emplace_back(new Foo());
    v.emplace_back(std::make_unique<Foo>());    

    v[0]->a = 1;
    v[1]->a = 2;

    const std::vector<ucp_ptr<Foo>>& cv = v;

    std::cout << cv[0]->a << std::endl; //<-read access OK
    //cv[1]->a = 10; //<-compiler error
}
#包括
#包括
#包括
//保持常量的唯一指针
模板
类ucp\U ptr{
std::唯一的ptr ptr;
公众:
ucp_ptr()=默认值;
ucp_ptr(T*ptr):ptr{ptr}{};
ucp_ptr(std::unique_ptr&&other):ptr(std::move(other)){};
运算符*(){return ptr.get();}
T const&运算符*()const{return ptr.get();}
T*运算符->(){return ptr.get();}
T const*运算符->()const{return ptr.get();}
};
结构Foo{
int a=0;
};
int main(){
std::向量v;
v、 放回(新Foo());
v、 向后放置(std::make_unique());
v[0]>a=1;
v[1]>a=2;
常数std::向量&cv=v;

std::在您切换到C++11(从C++03?有或没有
boost
?)之前,是否可以发布没有此问题的代码。我无法想象仅仅通过引入
unique_ptr
,这个问题怎么会出现。仅供参考,如果在向量中存储智能指针的唯一原因是为了将大量资源保留在堆上,那么您不需要这样做,因为向量已经将其内容存储在堆上。与常量问题无关(假设这对你的问题很重要),但如果你想共享指针,那么也许你实际上并不想要
unique\u ptr
…anatolyg:没有智能指针,我会从一个向量转换到另一个向量Galik:returning/push back/等等。一个实体重资源的向量会复制它们,这从定义上讲是昂贵的。我不想共享所有权,只允许查看参考资料。我会重述上面的评论,只是为了鼓励大家讨论对所有权的理解:“我不想分享所有权,只允许对资源的只读访问。”据我所知,在中使用shared_ptr会使所有权分散。在适当的体系结构中,您可以清楚地指出所有权。我同意应该避免使用
std::shared_ptr
,除非您无法控制需要删除资源的对象。这完全取决于您;但是,您试图使用
unique_ptr
并注意到您遇到了困难,而
共享ptr
做了您需要它做的事情。如果我有一些
资源管理器
并且需要临时借出资源,我肯定会使用
共享ptr
。正如建议的那样,您可以创建助手访问函数,但如果允许调用方执行这些操作,那么这将非常繁琐对象有多个方面。
shared\u ptr
满足您的需要:它共享访问权限。这实际上并没有解决问题。OP希望返回指向
const
的指针集合。它们是原始的、唯一的还是共享的,实际上解决了不同的问题,并且只与方法的写入方式有关n、 这要求将包含GetVectorOfResources的类视为集合。我认为这是有意义的。接下来还有一件事:如果一个类将某个处理的结果返回为
vector
(它将结果的所有权传递给调用者),该怎么办,它应该用于一些后续处理:vector result1=_processor1.Process();//translation auto result2=_processor2.Process(translatedResult);//Process的参数是vector`在这种情况下,您可以使
decltype(_processor2)::Process
取而代之的是一个范围,并传递间接迭代器
class Bar {
    std::vector<ucp_ptr<Foo>> v;
public:
    void add(const Foo& foo){ 
        v.push_back(std::make_unique<Foo>(foo)); 
    }
    //modifying elements
    void doubleElements() {
        for (auto& e : v){
            e->a *= 2;
        }
    }
    const std::vector<ucp_ptr<Foo>>& showElements() const{
        return v;
    }
};