【问题标题】:Can I use a reinterpret_cast here?我可以在这里使用 reinterpret_cast 吗?
【发布时间】:2014-07-14 10:08:00
【问题描述】:

简化,我有以下类模板:

template<class T> class Buffer{
  char * ptr;
  T * getPtr(){return (T*)ptr;} // (1) Which cast to use ?
}

当我还不知道它们的类型 T 时,这些 Buffer 中的一些是从一个文件中生成并存储到一个数组中的。

Buffer<char> buffers[10];
do_something_to_load_buffers_from_file();

最后,当我知道它们的类型时,我想通过一个函数按值返回它们:

template<class T> Buffer<T> getBuffer(int i){
  return (Buffer<T>)buffers[i]; // (2) Which cast to use ?
}
...
Buffer<int> ibuf = getBuffer<int>(5);

现在的问题是:我在标记线上使用哪些演员表? (在给定的示例中,我有意使用 C 样式转换作为 PLACEHOLDER。)

标记 (1): 重新诠释演员应该在这里做正确的事,是这样吗?

标记(2):

  • 重新解释演员表也可以在这里完成这项工作,但这是一种好的做法吗?
  • 对于我的一般理解:这一行将首先调用转换构造函数 Buffer(Buffer& b),返回后调用移动构造函数。对吗?

【问题讨论】:

  • C 风格的演员表从来都不是一个好主意。
  • @n.m.:OP 声明它是 C++ 演员之一的占位符。
  • 为什么首先是char * ptr;,而不是T * ptr;
  • 对于 Mark2,为什么不创建一个特定的构造函数?
  • 为什么是char * ptr?对,我也可以使用 T * ptr。但是,尽管如此,我还是必须强制转换,因为首先我将缓冲区作为纯字符从文件中加载,而不知道它的实际类型。稍后,我将使用 getBuffer(...) 来获取具有正确类型的缓冲区。

标签: c++ casting type-conversion reinterpret-cast


【解决方案1】:

您可以使用以下内容:

template<class T> class Buffer{
  char * ptr;
  T * getPtr(){return reinterpret_cast<T*>(ptr);}

  template<typename U>
  Buffer(const Buffer<U>& rhs) : ptr(rhs.ptr) {}
};

等以后:

template<class T> Buffer<T> getBuffer(int i){
  return buffers[i];
}

【讨论】:

  • +1 将整体理念及其优点放在首位,这可以/将把任何东西变成其他任何东西,并且通过模板构造函数进行交叉输入是优雅的。原始指针的所有权显然是一个问题,但它仍然是一种有趣的方法。
【解决方案2】:
  1. reinterpret_cast 是这里显而易见的选择,因为这就是我们正在做的事情:重新解释存储在 char* 中的位模式,就像它是 T* 一样。
  2. 这里没有内置演员表是个好主意。 Buffer&lt;char&gt;Buffer&lt;T&gt; 不相关。它们的布局兼容性没有任何保证(或者至少您需要非常仔细地定义它们以确保布局兼容性)。在char* 比其他指针长的平台上,这很可能难以解决。

一种可能的处理方法是:

class Buffer{
  char * ptr;
  template <typename T>
  T * getPtr() {return reinterpret_cast<T*>(ptr);}
};

另一种方法是跨类型复制Buffer&lt;T&gt;,正如另一个答案所暗示的那样。

【讨论】:

    猜你喜欢
    • 2013-10-18
    • 2017-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多