c++ - POD 类型如何添加对reinterpret_cast 的支持?

标签 c++ reinterpret-cast

我正在尝试替换类型,typedef从内置整型类型中获得,在具有自定义类的大型项目中使用,这将实现一些附加功能,例如避免赋值时截断等。但是该项目广泛使用像 reinterpret_cast<void*>(value) 这样的转换。 。我做了一个天真的尝试来实现 operator void*()在我的新类(class)中,但显然这并不能reinterpret_cast ,只允许static_castvoid* 。代码如下:

#include <cstdlib>
#include <type_traits>

#define USE_NEW_VALUE_TYPE
#ifdef USE_NEW_VALUE_TYPE
struct Value
{
    size_t value;
    operator void* () { return reinterpret_cast<void*>(value); }
};
static_assert(std::is_pod<Value>::value,"Value is not POD");
#else
typedef size_t Value;
#endif

int main()
{
    Value v{5};
    void* p=reinterpret_cast<void*>(v); // This is how the project uses it
}

我认为如果该类是 POD,这将允许我做类似 reinterpret_cast 这样的事情。但这段代码给了我一个编译错误:

invalid cast from type ‘Value’ to type ‘void*’

所以我的问题是:如何添加对这样的 reinterpret_cast 的支持,这样我就不必手动将其切换到 static_cast在项目的每个部分?

最佳答案

不幸的是,reinterpret_cast 并不是为此而设计的。这适用于 POD 类型的原因是 cppreference website 上的#3。 :

A value of any integral or enumeration type can be converted to a pointer type. A pointer converted to an integer of sufficient size and back to the same pointer type is guaranteed to have its original value, otherwise the resulting pointer cannot be dereferenced safely (the round-trip conversion in the opposite direction is not guaranteed; the same pointer may have multiple integer representations) The null pointer constant NULL or integer zero is not guaranteed to yield the null pointer value of the target type; static_cast or implicit conversion should be used for this purpose.

而且,我相信 §12.3.2 在这里发挥着作用:

A conversion function is never used to convert a (possibly cv-qualified) object to the (possibly cv-qualified) same object type (or a reference to it), to a (possibly cv-qualified) base class of that type (or a reference to it), or to (possibly cv-qualified) void.

简而言之:用户定义的转换不参与reinterpret_casts的解析。

可能的解决方案

1.显式取v的地址:

 void* p=reinterpret_cast<void*>(&v);

2.按照您的方式定义了operator void*(),您可以编写

void *p = v;

注意:这可能会由于不需要的隐式转换而引发一系列问题

3.按照您自己所说使用static_cast

注意:使用 &v 而不是定义 operator void*() ,原因与第 2 条相同

4. 理想情况下,但可能不切实际,修复需要将类强制转换为 void 的底层设计问题

没有。 3 可能是这里最不痛苦的解决方案。

编辑评论

这里有两种方法:

1. 使用重载的取址运算符 (operator&)。这可能无法实现,具体取决于 Value 的使用方式。

#include <cstdlib>

struct Value
{
    size_t value;
    void* operator &() { return reinterpret_cast<void*>(value); }
};

int main()
{
    Value v;    
    void* p=reinterpret_cast<void*>(&v); // This is how the project uses it
}

2.实现一个运算符uintptr_t。虽然这需要详细的双重转换,但它将转换转移到 Value 类中,并且 uintptr_tguaranteed能够容纳 void*

#include <cstdlib>

struct Value
{
    size_t value;
    operator uintptr_t() { return static_cast<uintptr_t>(value); }
};

int main()
{
    Value v;
    void* p=reinterpret_cast<void*>(static_cast<uintptr_t>(v)); // This is how the project uses it
    // or less verbose
    void* p2=reinterpret_cast<void*>(uintptr_t(v)); 

}

关于c++ - POD 类型如何添加对reinterpret_cast 的支持?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31673850/

相关文章:

c++ - 重新诠释

c++ - reinterpret_cast(或任何强制转换)可以将 xvalues 转换为 lvalues 吗?

c++ - pthread读写锁不起作用吗?

c++ - '转换' 5 个字符为 int

c++ - 在彼此非常接近的范围内混合二进制数据和指令是否有缓存惩罚?

c++ - 迷宫生成 - 递归除法(它是如何工作的?)

c++ - Reinterpret_cast 在 C++ 中的使用

python - 如何在 pythran/numpy 中查看强制转换/重新解释强制转换?

c++ - reinterpret_cast 是如何工作的?

c++ - 更改 cin (c++) 的分隔符