如何在没有警告的情况下“安全”地施法到虚空**?

How to "safely" cast to void** without warning?

提问人:KAYSER 提问时间:10/3/2023 更新时间:10/3/2023 访问量:106

问:

我正在使用 SDL 创建一个简单的游戏。我到了需要使用 SDL_LockTexture 函数的地步,所以我编写了以下代码。

uint8_t* pixels = nullptr;
int pitch = 0;
SDL_LockTexture(textures[texture_index], nullptr, reinterpret_cast<void**>(&pixels), &pitch);

然而,叮叮当当警告我不要使用reinterpret_cast。所以我尝试用static_cast替换它,但static_cast给了我一个编译错误。代码本身工作正常,但警告很烦人。如何以 C++ 样式安全地转换为 void**?

C++ 强制转换

评论

0赞 Some programmer dude 10/3/2023
使用 类型的临时变量,然后传递指向它的指针。然后不需要显式转换(也称为强制转换)。void*

答:

4赞 Yakk - Adam Nevraumont 10/3/2023 #1

创建一个 .将指向该函数的指针传递给该函数。void* vpixels

然后静态强制转换为像素指针类型。void*

你可以编写一个帮手来为你做这件事:

template<class T>
struct out_ptr {
  // could be private, I'm just being pithy.  Also, could block
  // copy/move, they aren't sane.
  T** out;
  void* temp = nullptr;

  // You construct an out_ptr with an lvalue of the pointer
  // you want to write to.  I chose this over `T**` because
  // we require it to be a valid reference, and `out_ptr` seems
  // to indicate writing strongly enough.
  out_ptr(T*& p) : out(&p) {}

  // implicit cast to void**, so we can use this where SDL
  // supports an out-pointer parameter.  It is rvalue qualified,
  // as I do not expect out_ptrs to live beyond temporary (and
  // don't really work if you do that, honestly).
  operator void**() && {
    return &temp;
  }

  // we write to the pointer we are constructed with when we are
  // destroyed.  If you use this as intended, this happens at the
  // end of the full-expression with the function call where we
  // populated &temp with the data we want.
  ~out_ptr() {
    *out = static_cast<T*>(temp);
  }
};

用:

SDL_LockTexture(textures[texture_index], nullptr, out_ptr{pixels}, &pitch);

这依赖于 CTAD:如果没有它,您将需要一个辅助函数,而不是直接调用构造函数。