有没有在std容器中使用unique_ptr的透明方法? [英] Is there a transparent way of using unique_ptr in std containers?

查看:74
本文介绍了有没有在std容器中使用unique_ptr的透明方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否在容器中使用 std :: unique_ptr 的透明方法?

  #include< iostream> 
#include< memory>
#include< map>

结构方法{
virtual〜method(){std :: cout<< f\n; };
};
typedef std :: unique_ptr< method> MPTR;

std :: map< int,MPTR> tbl;

void insert(int id,method * m){
tbl.insert({id,std :: unique_ptr< method>(m)});;
};

void set(int id,method * m){
tbl [id] = std :: unique_ptr< method>(m);
};

int main(int argc,char ** argv){

insert(1,new method());
set(1,new method());
返回0;
}

我想使用 tbl.insert( {id,m}); tbl [id] = m; 等,而不必为每次访问都进行包装。 p>


  • 是否有用于unique_ptr的std容器的实现?尤其是 std :: map

  • 如何实现透明接口?


解决方案

当您将原始指针传递到函数中时,通常不知道谁会在指针指向对象时保留指向对象的所有权函数退出-调用方或被调用方。语言中没有任何东西可以指定或强制执行此操作。



因此,通常好的做法是,仅当被调用方读取或修改对象时,才传递原始指针。



在您的示例中,情况并非如此。您希望您的函数拥有分配的方法对象的所有权。因此,您应该更改函数以按值传递 std :: unique_ptr< method> 对象,而不是传递原始的 method * 指针。这就非常明确地表明,期望所有权将从呼叫者转移到被呼叫者,例如:

  #include< iostream> 
#include< memory>
#include< map>

结构方法{
virtual〜method(){std :: cout<< f\n; };
};
typedef std :: unique_ptr< method> MPTR;

std :: map< int,MPTR> tbl;

void insert(int id,MPTR m){
tbl.insert(std :: make_pair(id,std :: move(m)));;
};

void set(int id,MPTR m){
tbl [id] = std :: move(m);
};

int main()
{
insert(1,MPTR(new method)); //或在C ++ 14和更高版本的
set(1,MPTR(new method))中插入(1,std ::: make_unique< method>()); //或set(1,std ::: make_unique< method>())在C ++ 14中,然后
返回0;
}

实时演示


Is there a transparent way of using std::unique_ptr in containers?

#include <iostream>                                                                                                                         
#include <memory>                                                                                                                           
#include <map>                                                                                                                              

struct method {                                                                                                                             
    virtual ~method() { std::cout << "f\n"; };                                                                                              
};                                                                                                                                          
typedef std::unique_ptr<method> MPTR;                                                                                                       

std::map<int, MPTR> tbl;                                                                                                                    

void insert(int id, method *m) {                                                                                                            
    tbl.insert({id,std::unique_ptr<method>(m)});                                                                                            
};                                                                                                                                          

void set(int id, method *m) {                                                                                                               
    tbl[id] = std::unique_ptr<method>(m);                                                                                                   
};                                                                                                                                          

int main(int argc, char **argv) {                                                                                                           

    insert(1,new method());                                                                                                                 
    set(1,new method());                                                                                                                    
    return 0;                                                                                                                               
}   

I'd like to use tbl.insert({id,m}); and tbl[id] = m; etc. instead of having to wrap/unwrap for each access.

  • Are there implementations of std containers for unique_ptr? In particular std::map.
  • How would a transparent interface be implemented?

解决方案

When you pass a raw pointer into a function, it is generally unknown who is expected to keep ownership of the pointed-to object when the function exits - the caller or the callee. There is nothing in the language to specify or enforce that.

So, it is generally good practice to pass in a raw pointer only when the callee reads or modifies the object but the caller is expected to maintain ownership.

In your example, that is not the case. You want your functions to take ownership of the allocated method objects. So, you should change your functions to pass in std::unique_ptr<method> objects by value, instead of passing raw method* pointers. That makes it very explicit that ownership is expected to pass from the caller to the callee, eg:

#include <iostream>
#include <memory>
#include <map>

struct method {
    virtual ~method() { std::cout << "f\n"; };
};
typedef std::unique_ptr<method> MPTR;

std::map<int, MPTR> tbl;

void insert(int id, MPTR m) {
    tbl.insert(std::make_pair(id, std::move(m)));
};

void set(int id, MPTR m) {
    tbl[id] = std::move(m);
};

int main()
{
    insert(1, MPTR(new method)); // or insert(1, std:::make_unique<method>()) in C++14 and later
    set(1, MPTR(new method)); // or set(1, std:::make_unique<method>()) in C++14 and later
    return 0;                                                                                                                               
}

Live demo

这篇关于有没有在std容器中使用unique_ptr的透明方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆