The Feasibility of converting unique_ptr < T > into T * through reinterpret_cast

projects all use modern CPP,. In principle, they don"t have bare pointers. They all use STL smart pointers

.

but in the library used, there is a function that asks for a T * *, and unique_ptr itself does not provide a reference to return the encapsulated pointer, so I really can"t think of any way to get the pointer inside the unique_ptr and pass its reference to the function that requires T * * arguments

The

library is encapsulated in dll. You can only see its declaration, not its internal implementation

.

then I thought of using reinterpret_cast

but I don"t know much about the underlying layer, so I really don"t dare to use

.

I wrote a demo, that seems to be feasible in this way

-sharpinclude <iostream>

using namespace std;
struct s {
    string a;
    string b;
    string c;
};
void func(s **obj) {
    cout << (*obj)->a << endl;
    cout << (*obj)->b << endl;
    cout << (*obj)->c << endl;
}
int main(int argc, char *argv[]) {
    unique_ptr<s> p {new s({"123", "sdfadsf", "43g43g4g"})};
    func(reinterpret_cast<s **>(&p));
}

I don"t dare to use it because I don"t know the standard and the underlying implementation. I need the guidance of all the great gods

.

if this is not feasible, is there no other way but to change the original pointer and build your own wheel (forget the evil method of calculating offset.)

Dec.04,2021

using reinterpret_cast in this way results in UB. Even in a specific environment, forced use will not guarantee compatibility, portability, and so on.
you can do some checks before conversion, such as

static_assert(
  sizeof(int *) == sizeof(std::unique_ptr<int>) &&
  std::is_standard_layout_v<std::unique_ptr<int>>, "");

it is not legal to use reinterpret_cast here.

< hr >

legal practice:

because the parameter of func is a secondary pointer, you actually need to release the ownership of unique_ptr, then call it, and finally set the temporary pointer back to unique_ptr, that is,

.
int foo_init(foo** fp) 
{
  if (fp == nullptr)
    return -1;
  if (*fp == nullptr) {
    *fp = malloc(sizeof(foo));
    if (*fp == nullptr)
      return -1;
  }
  return foo_init_internal(*fp);
}

//1,foo_init,foo_release,foo_free
foo* fp = nullptr;
foo_init(&fp);
foo_release(fp);
foo_free(&fp);
//2,,,foo_init,,foo_release,
foo f;
foo* fp = &f;
foo_init(&fp);
foo_release(fp);
Menu