移植WTL应用到C++20:atlwin.h中Create方法传临时RECT的问题求助
解决WTL Create方法在C++20中无法传入临时CRect的问题
问题根源
C++20收紧了临时对象绑定规则,临时CRect对象无法绑定到_U_RECT构造函数要求的非const左值引用(RECT&),导致原代码中直接传CRect(0,0,100,200)的调用方式失效。
可行解决方案
1. 扩展_U_RECT的构造函数
在项目公共头文件中(需确保在包含atlwin.h之后引入),添加适配临时对象的构造函数:
namespace ATL { // 新增接受RECT右值引用的构造函数 inline _U_RECT::_U_RECT(RECT&& r) : m_pRect(&r) {} // 针对CRect的重载,利用CRect继承RECT的特性 inline _U_RECT::_U_RECT(CRect&& r) : m_pRect(&r) {} }
临时对象的生命周期会覆盖Create方法的执行过程,不会出现悬空指针问题,原有调用代码无需修改即可正常工作。
2. 定义宏简化临时变量传递
如果不想修改ATL类定义,可通过宏自动创建可复用的临时CRect变量:
#define CRCT(x1,y1,x2,y2) [&]() -> CRect& { static CRect r; r.SetRect(x1,y1,x2,y2); return r; }()
调用时替换原临时对象写法:
Create(hWnd, CRCT(0,0,100,200), ....);
宏内部用lambda创建静态CRect,每次调用更新其值,返回左值引用满足_U_RECT的参数要求。
3. 重载自定义窗口类的Create方法
如果项目窗口类均为自定义派生类,可在基类中新增适配临时CRect的重载:
template <typename T> class MyBaseWindow : public CWindowImpl<T> { public: HWND Create(HWND hWndParent, CRect&& rect, LPCTSTR szWindowName = NULL, DWORD dwStyle = 0, DWORD dwExStyle = 0, _U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) { return CWindowImpl<T>::Create(hWndParent, rect, szWindowName, dwStyle, dwExStyle, MenuOrID, lpCreateParam); } };
让所有窗口类继承MyBaseWindow,原有的临时对象调用方式即可直接复用。
内容的提问来源于stack exchange,提问作者bpeikes
相关产品推荐
相关产品推荐

