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

移植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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 19:03:08