C++中如何让相同底层类型的不同typedef别名被判定为不同类型
原因说明
你遇到的判断结果符合C++标准定义:typedef 本质是给现有类型创建透明别名,不会生成新的独立类型,你定义的 TA 和 TB 都是 void* 类型的不同名称,所以 std::is_same、typeid 等类型比较操作都会判定二者相同。
要实现让两个类型判定为不同的需求,你需要主动创建两个独立的新类型,可选的实现方案如下:
方案1:无依赖原生实现(兼容所有C++版本)
直接将 void* 封装到两个不同的空结构体中,不需要引入任何第三方依赖:
// 两个独立的结构体类型,天然互不相同 struct TA { void* raw_ptr; // 可选:重载指针相关运算符,使用体验和原生指针一致 void* operator->() const { return raw_ptr; } operator void*() const { return raw_ptr; } }; struct TB { void* raw_ptr; // 可选:和TA一致重载相关运算符 };
此时 std::is_same_v<TA, TB> 会直接返回 false,满足你的需求。
方案2:宏封装减少重复代码
如果需要大量定义这类强类型指针,可以封装通用宏来避免重复编码:
#define STRONG_PTR_ALIAS(NewAlias) \ struct NewAlias { \ void* raw_ptr; \ operator void*() const { return raw_ptr; } \ explicit NewAlias(void* p = nullptr) : raw_ptr(p) {} \ }; // 一行代码生成独立的指针类型 STRONG_PTR_ALIAS(TA) STRONG_PTR_ALIAS(TB)
你可以根据自己的需求调整宏的实现,比如添加更多运算符重载、支持任意原始类型等。
方案3:C++20 零开销轻量实现
如果你使用C++20及以上版本,可以用标签模板实现无额外内存开销的强类型指针:
template<typename Tag> struct StrongVoidPtr { void* raw_ptr; // 按需添加运算符重载 }; // 用不同的标签类型生成完全独立的指针类型 using TA = StrongVoidPtr<struct TagA>; using TB = StrongVoidPtr<struct TagB>;
该实现利用空基类优化,生成的 TA、TB 大小和原生 void* 完全一致,没有任何额外性能开销。
内容的提问来源于stack exchange,提问作者Konstantin
相关产品推荐
相关产品推荐

