c++ - Is this approach of moving data from standard containers to shared pointers correct? -


here problem: have std::string defined in function. need extend scope of string because of asynchronous operation. naturally can copy shared pointer this:

{ std::string hi{"hi"}; auto shared_hi = std::make_shared<std::string>(hi); //insert shared_hi in async queue } 

the problem strings very big, , vectors, , std::arrays. not avoid copy, have function can "steal" data out of containers without having copy them. i've come clever solution posted below, i'm wondering if there isn't better solution this. if there isn't, i'd know if doing i'm doing below defined behavior:

template<class t> class wrappeddeleter { public:   wrappeddeleter(t  &&other): o_(std::move(other)) {   } private:   t o_; };  //this function creates deleter scope template<class p, class t> std::function<void(p *)> make_delete(t  &&encapsulate) {   wrappeddeleter<t> *d = new wrappeddeleter<t>(std::move(encapsulate));   return [d](p * ptr) {     std::cout << "deleting now\n";     delete d;   }; }  template<class p, class c> std::shared_ptr<p> steal_data(c  &&data) {   p *ptr = data.data();   //can't use make_shared - custom deleter   return std::shared_ptr<p>(ptr, make_delete<p, c>(std::move(data))); } 

used this:

int main() {     {         std::shared_ptr<int> p_a;         std::shared_ptr<int> p_b;         std::shared_ptr<const char> p_c;          {             std::array<int,3> a= {{1,2,3}};             std::vector<int> b= {1,2,3};             std::string c= {"hello world"};             p_a = steal_data<int,std::array<int,3> >(std::move(a));             p_b = steal_data<int, std::vector<int> >(std::move(b));             p_c = steal_data<const char, std::string>(std::move(c));             std::cout << "inside" << *p_a << " " << *p_b << " " << p_c.get() << std::endl;         }         std::cout << "outside" << *p_a << " " << *p_b << " " << p_c.get() << std::endl;           std::cout << "end of scope\n";     }     return 0; } 

as praetorian says, sensible way move data shared_ptr using make_shared<t>(move(obj)). if want shared_ptr point underlying contiguous data block rather container itself, can use alias constructor template<class y> shared_ptr(const shared_ptr<y>& r, t *ptr);:

std::vector<int> v{1, 2, 3}; auto cptr = std::make_shared<std::vector<int>>(std::move(v)); std::shared_ptr<int> ptr{cptr, cptr->data()}; 

as function:

template<typename container> std::shared_ptr<container::value_type> steal_data(container &&cont) {     auto cptr = std::make_shared<container>(std::move(cont));     return {cptr, cptr->data()}; } 

Comments

Popular posts from this blog

python - Subclassed QStyledItemDelegate ignores Stylesheet -

java - HttpClient 3.1 Connection pooling vs HttpClient 4.3.2 -

SQL: Divide the sum of values in one table with the count of rows in another -