You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何pointer_cast替代C风格转换给CMapStringToPtr::Lookup传参会失败

问题根因

你遇到的问题核心是自定义pointer_cast的返回值是右值临时对象,无法正确匹配CMapStringToPtr::Lookup的第二个参数要求。

CMapStringToPtr::Lookup的第二个参数是void*&类型的非常量左值引用,作用是把查询到的指针结果写入传入的变量:

  • 原来的C风格强转(void*&)psEvent是直接对psEvent本身做类型重解释,相当于给SPECIAL_EVENT_S*类型的psEvent取了一个void*类型的别名,Lookup写入时直接修改的是psEvent本身的取值,逻辑正常。
  • 你自定义的pointer_cast是按值返回,返回的void*&实际是临时右值对象,即使微软编译器的非标准扩展允许临时值绑定到非常量左值引用(所以编译无报错),Lookup写入的也只是这个临时对象,原psEvent的取值完全没有被修改,自然后续判断为空,无法进入分支。

现代规范写法

优先用更安全、无歧义的显式临时变量接收写法,避免对指针引用做强制转换:

void* pLookupBuf = nullptr;
// 无需强转,直接传入void*类型变量接收查询结果
if (m_pMapSPtrEvents->Lookup(strKey, pLookupBuf))
{
    // 从void*转回实际类型用static_cast即可,比reinterpret_cast更安全
    auto* psEvent = static_cast<SPECIAL_EVENT_S*>(pLookupBuf);
    if (psEvent != nullptr)
    {
        bActivate = TRUE;
        strTipText = psEvent->strEvent;
    }
}

这种写法完全符合C++标准,没有任何未定义行为,可读性也更高。

如果希望沿用原来的写法风格,不新增临时变量,可以直接用标准C++的reinterpret_cast做引用转换,不需要用自定义的pointer_cast:

if (m_pMapSPtrEvents->Lookup(strKey, reinterpret_cast<void*&>(psEvent)))

reinterpret_cast转换左值引用时返回的是左值,可以正常绑定到Lookup的非常量左值引用参数,效果和原来的C风格强转完全一致,同时比C风格强转更易识别、更符合现代C++规范。


去掉&后编译报错的原因

去掉&后pointer_cast返回的是void*类型的右值,而Lookup要求参数是可修改的void*&左值引用,右值无法绑定到该类型参数,因此编译失败。

内容的提问来源于stack exchange,提问作者Andrew Truckle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 13:24:03