Home > Net >  How to pass raw pointer of unique_ptr to a function that takes in unique_ptr?
How to pass raw pointer of unique_ptr to a function that takes in unique_ptr?

Time:08-15

#include <iomanip>
#include <iostream>
#include <memory>
#include <string>
#include <type_traits>
#include <utility>

class Res {
        std::string s;
    public:
        Res(std::string arg) : s{ std::move(arg) } {
            std::cout << "Res::Res(" << s << ");\n";
        }
        ~Res() {
            std::cout << "Res::~Res();\n";
       }
    private:
       friend std::ostream& operator<< (std::ostream& os, Res const& r) {
           return os << "Res { s = " << r.s << "; }";
       }

};

// ptr is used just to read the content of the ptr.
// No writing is done. fun2 calls another api 
// lets say api_fun that requires unique_ptr
void fun2(std::unique_ptr<Res>& uniq_ptr){
    // api_fun(uniq_ptr);
    std::cout << uniq_ptr.get() << '\n';
}

void fun1(Res* ptr){
    //std::unique_ptr<Res> tt(ptr);
    //fun2(std::move(tt));// this deletes the mem twice.
}

int main()
{
    std::unique_ptr<Res> up(new Res("Hello, world!"));
    fun1(up.get());
    // up will be used here too
}

I am working on a project that has a unique_ptr variable lets say up. This unique_ptr up is passed to a function fun1 as raw pointer. Now inside fun1 I have to call function fun2 but it takes unique_ptr.

As mentioned in the comment of fun2. This function only reads the content of the pointer no modification is done.

How do I pass unique_ptr to fun2 from a raw pointer?

Ps: Is there a solution without modifying the api definition?

Edit: fun2 can takes std::unique_ptr&

CodePudding user response:

instead of passing the address with get() you must release the ownership with release()

void api_fun(std::unique_ptr<Res> const&);

void fun2(std::unique_ptr<Res>& uniq_ptr){
  api_fun(uniq_ptr);
  std::cout << uniq_ptr.get() << '\n';
}

void fun1(Res* ptr){
  std::unique_ptr<Res> tt(ptr);
  fun2(tt);
  tt.release();
}

int main()
{
    std::unique_ptr<Res> up(new Res("Hello, world!"));
    auto p = up.release();
    fun1(p);
    up.reset(p);
    std::cout << "All good" << std::endl;
}

but these fun1 and fun2 are not fun at all for anyone who is going to work with it later ;)

Surprisingly it looks exception-safe.

  • Related