【发布时间】:2021-10-23 16:45:03
【问题描述】:
这个if 测试工作正常(已经做了多年):
if (m_pMapSPtrEvents->Lookup(strKey, (void*&)psEvent))
{
if (psEvent != nullptr)
{
bActivate = TRUE;
strTipText = psEvent->strEvent;
}
}
但是如果我把它改成:
if (m_pMapSPtrEvents->Lookup(strKey, pointer_cast<void*&>(psEvent)))
{
if (psEvent != nullptr)
{
bActivate = TRUE;
strTipText = psEvent->strEvent;
}
}
`pointer_cast 在哪里:
template<typename T, typename U> static T inline pointer_cast(U src) noexcept
{
static_assert(sizeof(T) >= sizeof(U), "Invalid pointer cast"); // Check sizes!
__pragma(warning(suppress:26490)) // Note: no semicolon after this expression!
return reinterpret_cast<T>(src);
}
失败了。投射结构指针 (SPECIAL_EVENT_S *psEvent) 的现代方式是什么?
m_pMapSPtrEvents 的类型为 CMapStringToPtr。
我应该指出:
- 我在 IDE 中没有收到任何视觉警告。
- 编译没有错误。
- 我运行它时它不会断言。
- 但它不会检测到
if子句,因此不会显示工具提示。
...除非我恢复到 c 风格的演员表。
更新
如果我按照建议删除&,则会出现构建错误:
4>MyMonthCalCtrl.cpp
4>D:\My Programs\2022\MeetSchedAssist\Meeting Schedule Assistant\MyMonthCalCtrl.cpp(72,8): error C2664: 'BOOL CMapStringToPtr::Lookup(LPCTSTR,void *&) const': cannot convert argument 2 from 'T' to 'void *&'
4> with
4> [
4> T=void *
4> ]
4>C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.30.30704\atlmfc\include\afxcoll.h(1264,7): message : see declaration of 'CMapStringToPtr::Lookup'
4>Done building project "Meeting Schedule Assistant.vcxproj" -- FAILED.
【问题讨论】:
-
如果您删除演员表中的参考规范(
&)会发生什么?无论如何,我猜Lookup函数调用会作为参考。 -
我知道。但我认为引用类型在某种程度上令人困惑。如果按照我链接的答案中的建议,存在某种未检测到的
void*类型的取消引用,那么这将在各种工作中抛出各种扳手。也许我需要修改pointer_cast的代码... -
该函数在
return reinterpret_cast<T>(src)下看起来确实很奇怪,我收到警告“局部变量或临时的返回地址:src”。尝试使用m_pMapSPtrEvents->Lookup(strKey, reinterpret_cast<void*&>(psEvent)) -
是的 - 需要重新考虑
pointer_cast来处理引用类型转换。我会看看我是否能想出至少一个quick-fix来警告/失败这些类型,虽然...... -
作为权宜之计,您可以将其添加为
pointer_cast函数的第一行:static_assert(!std::is_reference<T>::value, "Cannot pointer_cast to a reference!");(您还需要#include <type_traits>)。
标签: visual-c++ casting mfc