首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用gsl::窄带失败

使用gsl::窄带失败
EN

Stack Overflow用户
提问于 2021-10-03 15:51:21
回答 1查看 94关注 0票数 1

我知道有类似的问题,我不知道这个最好的措辞。

我觉得有点讽刺的是,代码分析警告的原因首先是它让我将gsl::narrow用于两个实例:

实例1:

代码语言:javascript
复制
auto* pCell1 = gsl::narrow<CGridCellBase*>(lParam1);
auto* pCell2 = gsl::narrow<CGridCellBase*>(lParam2);

编译错误:

代码语言:javascript
复制
    6>D:\My Libraries\GSL-main\include\gsl\util(105,1): error C2440: 'static_cast': cannot convert from 'U' to 'T'
6>        with
6>        [
6>            U=LPARAM
6>        ]
6>        and
6>        [
6>            T=CGridCellBase *
6>        ]
6>D:\My Libraries\GSL-main\include\gsl\util(105,12): message : Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast

实例2:

代码语言:javascript
复制
auto* pItem = gsl::narrow<NM_GRIDVIEW*>(pNotifyStruct);

编译错误:

代码语言:javascript
复制
6>D:\My Libraries\GSL-main\include\gsl\narrow(58,1): error C2440: 'static_cast': cannot convert from 'const T' to 'U'
6>        with
6>        [
6>            T=NM_GRIDVIEW *
6>        ]
6>        and
6>        [
6>            U=NMHDR *
6>        ]
6>D:\My Libraries\GSL-main\include\gsl\narrow(58,9): message : Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

这些信息告诉我要做相反的事情:

  • 从整型到指针类型的转换需要reinterpret_cast、C样式的转换或函数类型的转换。
  • 指向的类型是不相关的;转换需要reinterpret_cast、C样式的强制转换或函数类型的转换。

绕圈转!鉴于当时的情况,我是否要明白,正确的做法是:

  1. reinterpret_cast和..。
  2. 添加适当的prama警告以抑制警告。

对,是这样?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-03 16:34:14

您不能(也不应该尝试)使用reinterpret_cast以外的任何东西在指针和非指针之间,或者在指向不同(无关)类型的指针之间进行转换。gsl::narrow函数只是static_cast理解gsl::狭义实现的一个“花哨”版本。

此外,在编写使用WinAPI或MFC的程序时,几乎不可能完全避免在指针类型和非指针类型之间进行转换;值得注意的是,许多消息处理例程将指向某些数据或其他数据的指针作为其lParam参数(根据目标平台的不同,LPARAM类型被定义为__int64int )。

所以,你的建议是,IMHO,最好的选择:

  1. reinterpret_cast和..。
  2. 添加适当的实用警告以抑制警告。

但是,您很可能需要在#pragma...中添加中的这个指令--在您的代码中放置了许多。因此,您可以做的是创建一个您自己的“助手”(或包装器)强制转换,然后您可以在整个代码中使用它。

例如,可以将以下内容添加到"stdafx.h“(或"pch.h")文件中(或添加到任何需要强制转换的头部):

代码语言:javascript
复制
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);
}

然后可以使用该pointer_cast,避免每次都要添加pragma。下面是一个典型的示例,使用自定义对话框类中WM_NOTIFY消息的潜在消息处理程序:

代码语言:javascript
复制
BOOL MyDialog::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT *pResult)
{
    NMHDR* pHdr = pointer_cast<NMHDR*>(lParam);
    switch (pHdr->code) {
        //... remaining code ...

注意:关于__pragma()指令的使用(而不是#pragma__),https://learn.microsoft.com/en-us/cpp/preprocessor/pragma-directives-and-the-pragma-keyword?view=msvc-160

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69426446

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档