为什么这里需要"const":VS C2664

Why "const" is needed here: VS C2664

本文关键字:VS C2664 const 为什么 这里      更新时间:2023-10-16

我从MSDN复制代码

它说"在Visual c++ 2005中,编译器现在强制执行应用const的c++标准要求。下面的示例生成C2664。"

// C2664d.cpp
// C2664 expected
#include <windows.h>
void func1(LPCSTR &s)
{
}
void func2(LPSTR &s)
{
   func1(s);
}
int main()
{
   return 0;
}

为什么我需要在这里使用"const" ?

(这些LPCSTR/LPSTR的类型名只会混淆代码。)

你在这里遇到的问题可以用以下简洁的方式表达

char *p = NULL;
const char *&r = p; // ERROR

这段代码不能编译的原因和你的原始版本不能编译的原因是一样的:这样的引用初始化在c++中是非法的。在您的示例中,相同的初始化在函数参数初始化中隐式使用(当从func2调用func1时),而在我的示例中,它是显式完成的。

不合法的原因与c++(和C)中T** -> const T**转换不合法的原因大致相同。这是一个旧的FAQ: http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.17.

基本上,如果上面示例中的初始化是合法的,则可以继续执行以下操作序列
const char cc = 0;
r = &cc; // OK. Note: `p` now points to `cc`!
*p = 1; // !!! Attempts to modify `cc` !!!

意味着它将允许我们在没有任何"hack"的情况下打破常量正确性规则,即不使用单个强制转换。这在c++(以及C)中被认为是不可接受的,这就是为什么不允许像T ** -> const T **这样的转换和像T *& -> const T *&这样的初始化。

还请注意,就像T** -> const T* const*转换在c++中是合法的一样(参见FAQ条目),T** -> const T* const&初始化也是合法的

char *p = 0;
const char *const &r = p; // OK

在该代码示例中,将生成C2664,因为代码试图将对指针的引用转换为对const指针的引用。这是两回事

允许将指针转换为const引用(const LPSTR&)

LPCSTR定义为"typedef CONST CHAR *LPCST"和LPCST定义为typepedef CHAR *LPCST

正如您所看到的,LPCSTR是const而LPSTR不是,所以这两种类型是不同的,因此您需要在上下文中使用const。