1

示例代码:

void COptionsDlg::OnBnClickedButtonMoreSettings()
{
    CString strCaption = _T("");
    const auto pMoreSettingsButton = GetDlgItem(IDC_BUTTON_MORE_SETTINGS);

    if (pMoreSettingsButton == nullptr)
        return;

    pMoreSettingsButton->GetWindowText(strCaption);

    __pragma(warning(suppress:26414))
        auto pDlgOther = std::make_unique<COtherSettingsSheet>(strCaption);
    if (pDlgOther != nullptr)
    {
        pDlgOther->DoModal();
    }
}

为什么编译器仍然抱怨这一行:

在此处输入图像描述

它仍然说:

C26462 : 指向的值pMoreSettingsButton只赋值一次,将其标记为指向const(con.4) 的指针。

我正在使用 Visual Studio 2022 Preview 6,并且在其他类文件中也注意到了这一点。是我做错了什么还是我应该向微软解决的错误?

4

1 回答 1

5

以下程序抓住了问题的要点,但不失一般性:

int* foo() { return nullptr; }

int main() {
    const auto p = foo();  // C26462
}

它产生C26462诊断,并继续提供解决方案:

将其标记为指向const

你可能认为这const auto正是这样做的,但事实并非如此。

编译器需要推断出要替换auto的内容。它查看函数声明foo()并明确得出结论,auto应该替换为int*. 那部分不是很有趣。这里唯一的惊喜可能是,C++ 走的是最少惊喜的路线。

因此,如果auto被替换为int*,很明显const auto应该变成const int*,即指向 的指针const,正如诊断消息所建议的那样。那为什么代码分析器还在抱怨呢?

好吧,在设计一门编程语言时,走最少惊喜的路线并不是您唯一的选择,C++ 也不羞于积极探索设计空间!const关键字的放置当然属于该类别:

从广义上讲,const适用于紧靠它左边的任何东西。这很简单,看似如此,与 C++ 非常不同。当然,还有一个特殊的规则,它看到如此频繁的应用,我们几乎完全忘记了它的特殊性:如果左边没有任何东西,const那么它就会应用到它右边的任何东西上。对于价值观来说,这并不重要:const int并且int const意味着同样的事情。但是,当涉及指针时,事情会变得更加有趣。const int*并且int* const意味着完全不同的东西。前者指定一个“指向”const指针,而后者是一个const指针”

回到这里的直接问题,const auto被翻译成auto const(通过特殊const规则),最后auto被替换,产生int* const(或CWnd* const在最初的问题陈述中)。这不是“指向”const指针。要解决此问题,您有两种选择:

  • 命名具体类型,即CWnd const*,或
  • 已经auto解决了其他问题,例如(注意导致编译器推断类型auto const*的尾随,并允许您对指针进行 cv 限定)*CWnd

无论哪种方式,您都应该考虑使用"consistent const",也称为"east const",并忘记const.

于 2021-10-23T16:52:06.183 回答