Error C2664: cannot convert from non const T* to const T*&

本文深入探讨了C++编程中引用与指针的区别与使用,详细解释了引用不可转换为非const引用的原因,并通过实例展示了错误C2664的产生机制与解决方法。

编写程序时遇到以下错误:

Error C2664: cannot convert from non const T* to const T*&

错误原因如下:


Q1:

The following code generates an incorrect compile error:


int* p;
int const* & r = p; // reference to a pointer to const int

error C2440: 'initializing' : cannot convert from 'int *' to 'const int *&'

     Conversion loses qualifiers


A1:

The error is correct. Due to the added layer of indirection, it is not safe to reference a pointer to an int through a pointer to a const int. Consider what could happen if it were allowed:

----------

int *p;
const int *&r = p;    // reference to a pointer to const int
const int immutable = 0;
r = &immutable;    // assign p to address of immutable
*p = 1;    // whoops, now 0 = 1!

----------


Q2:
#include<iostream>
using namespace std;
int f(int i)
{ return ++i;
}
int g(int & i)
{ return ++i;
}
int main()
{ int a=0,b=0;
 a+=g(g(a));
 a+=g(f(b));
 cout<<"a="<<a<<" b="<<b<<endl;
 return 1;
}
提示:
Compiling...
a.cpp
F:\C C++\ddd\a.cpp(11) : error C2664: 'g' : cannot convert parameter 1 from 'int' to 'int &'
        A reference that is not to 'const' cannot be bound to a non-lvalue
F:\C C++\ddd\a.cpp(12) : error C2664: 'g' : cannot convert parameter 1 from 'int' to 'int &'
        A reference that is not to 'const' cannot be bound to a non-lvalue


A2:

所谓引用,其实就是别名,一但起名后就不能改了,所有的行为跟原变量完全一样。类型当然要相同。
所以,一个非const的引用,其实指的是它引用的对像是non-const的。
你这裏犯的错误等於把一个const转为非const了。这是不允许的。

为什麼一个函数的返回值是const呢?因为函数返回值是放在栈上的,用完就回收,它的有效期只有包函它的语句为止。所以它只是个临时变量,编译器当然会认为他是不能修改的。

常数,常量,变量的值,都是const的。为了返回一个左值,你可以
int& f(int& i)
{ return i;
} 
这样,f(i)就等同於i。f(i)++等同於i++。
但最好不要
int& f(int i)
{ return ++i;
} 
犯了和返回临时变量的指针一样的错误。

Windows PowerShell 版权所有 (C) Microsoft Corporation。保留所有权利。 尝试新的跨平台 PowerShell https://aka.ms/pscore6 PS C:\Windows\system32&gt; cd D:\ExtCheats-main\ExtCheats-main\ExtCheats PS D:\ExtCheats-main\ExtCheats-main\ExtCheats&gt; g++ main.cpp Cheats.cpp Render.cpp globals.cpp ext/imgui/imgui.cpp ext/imgui/imgui_draw.cpp ext/imgui/imgui_impl_win32.cpp ext/imgui/imgui_tables.cpp ext/imgui/imgui_widgets.cpp ext/imgui/imgui_impl_dx11.cpp -o ExtCheats.exe -Iext/imgui -lopengl32 -lgdi32 -luser32 -ldwmapi -lws2_32 main.cpp: In function &#39;int WinMain(HINSTANCE, HINSTANCE, LPSTR, int)&#39;: main.cpp:114:21: error: cannot convert &#39;LPCWSTR&#39; {aka &#39;const wchar_t*&#39;} to &#39;LPCSTR&#39; {aka &#39;const char*&#39;} in assignment 114 | wc.lpszClassName = CLASS_NAME; | ^~~~~~~~~~ | | | LPCWSTR {aka const wchar_t*} main.cpp:125:20: error: cannot convert &#39;const wchar_t*&#39; to &#39;LPCSTR&#39; {aka &#39;const char*&#39;} 125 | MessageBox(NULL, L&quot;Error in allocate window&quot;, L&quot;Error&quot;, NULL); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | const wchar_t* In file included from D:/TDM/x86_64-w64-mingw32/include/Windows.h:72, from BasicStruct.hpp:2, from main.cpp:5: D:/TDM/x86_64-w64-mingw32/include/winuser.h:3711:54: note: initializing argument 2 of &#39;int MessageBoxA(HWND, LPCSTR, LPCSTR, UINT)&#39; 3711 | WINUSERAPI int WINAPI MessageBoxA(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT uType); | ~~~~~~~^~~~~~ main.cpp:132:30: error: cannot convert &#39;const wchar_t*&#39; to &#39;LPCSTR&#39; {aka &#39;const char*&#39;} 132 | HWND CS2 = FindWindow(NULL, L&quot;Counter-Strike 2&quot;); | ^~~~~~~~~~~~~~~~~~~ | | | const wchar_t* In file included from D:/TDM/x86_64-w64-mingw32/include/Windows.h:72, from BasicStruct.hpp:2, from main.cpp:5: D:/TDM/x86_64-w64-mingw32/include/winuser.h:3938:64: note: initializing argument 2 of &#39;HWND__* FindWindowA(LPCSTR, LPCSTR)&#39; 3938 | WINUSERAPI HWND WINAPI FindWindowA(LPCSTR lpClassName,LPCSTR lpWindowName); | ~~~~~~~^~~~~~~~~~~~ main.cpp:322:79: warning: passing NULL to non-pointer argument 5 of &#39;void* CreateThread(LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD)&#39; [-Wconversion-null] 322 | BHOPThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)BHOP, instance, NULL, NULL); | ^~~~ In file included from D:/TDM/x86_64-w64-mingw32/include/winbase.h:29, from D:/TDM/x86_64-w64-mingw32/include/Windows.h:70, from BasicStruct.hpp:2, from main.cpp:5: D:/TDM/x86_64-w64-mingw32/include/processthreadsapi.h:195:169: note: declared here 195 | WINBASEAPI HANDLE WINAPI CreateThread (LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId); | ~~~~~~^~~~~~~~~~~~~~~ main.cpp:330:91: warning: passing NULL to non-pointer argument 5 of &#39;void* CreateThread(LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD)&#39; [-Wconversion-null] 330 | TriggerBotThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)TriggerBot, instance, NULL, NULL); | ^~~~ In file included from D:/TDM/x86_64-w64-mingw32/include/winbase.h:29, from D:/TDM/x86_64-w64-mingw32/include/Windows.h:70, from BasicStruct.hpp:2, from main.cpp:5: D:/TDM/x86_64-w64-mingw32/include/processthreadsapi.h:195:169: note: declared here 195 | WINBASEAPI HANDLE WINAPI CreateThread (LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId); | ~~~~~~^~~~~~~~~~~~~~~ main.cpp:338:89: warning: passing NULL to non-pointer argument 5 of &#39;void* CreateThread(LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD)&#39; [-Wconversion-null] 338 | SimAimBotThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)SimAimBot, instance, NULL, NULL); | ^~~~ In file included from D:/TDM/x86_64-w64-mingw32/include/winbase.h:29, from D:/TDM/x86_64-w64-mingw32/include/Windows.h:70, from BasicStruct.hpp:2, from main.cpp:5: D:/TDM/x86_64-w64-mingw32/include/processthreadsapi.h:195:169: note: declared here 195 | WINBASEAPI HANDLE WINAPI CreateThread (LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId); | ~~~~~~^~~~~~~~~~~~~~~ main.cpp:347:83: warning: passing NULL to non-pointer argument 5 of &#39;void* CreateThread(LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD)&#39; [-Wconversion-null] 347 | AimBotThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)AimBot, instance, NULL, NULL); | ^~~~ In file included from D:/TDM/x86_64-w64-mingw32/include/winbase.h:29, from D:/TDM/x86_64-w64-mingw32/include/Windows.h:70, from BasicStruct.hpp:2, from main.cpp:5: D:/TDM/x86_64-w64-mingw32/include/processthreadsapi.h:195:169: note: declared here 195 | WINBASEAPI HANDLE WINAPI CreateThread (LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId); | ~~~~~~^~~~~~~~~~~~~~~ main.cpp:356:87: warning: passing NULL to non-pointer argument 5 of &#39;void* CreateThread(LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD)&#39; [-Wconversion-null] 356 | NoRcolioThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)NoRecoil, instance, NULL, NULL); | ^~~~ In file included from D:/TDM/x86_64-w64-mingw32/include/winbase.h:29, from D:/TDM/x86_64-w64-mingw32/include/Windows.h:70, from BasicStruct.hpp:2, from main.cpp:5: D:/TDM/x86_64-w64-mingw32/include/processthreadsapi.h:195:169: note: declared here 195 | WINBASEAPI HANDLE WINAPI CreateThread (LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId); | ~~~~~~^~~~~~~~~~~~~~~ main.cpp:364:93: warning: passing NULL to non-pointer argument 5 of &#39;void* CreateThread(LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD)&#39; [-Wconversion-null] 364 | AntiFlashThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)AntiFlashFunc, instance, NULL, NULL); | ^~~~ In file included from D:/TDM/x86_64-w64-mingw32/include/winbase.h:29, from D:/TDM/x86_64-w64-mingw32/include/Windows.h:70, from BasicStruct.hpp:2, from main.cpp:5: D:/TDM/x86_64-w64-mingw32/include/processthreadsapi.h:195:169: note: declared here 195 | WINBASEAPI HANDLE WINAPI CreateThread (LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId); | ~~~~~~^~~~~~~~~~~~~~~ main.cpp:400:22: error: cannot convert &#39;LPCSTR&#39; {aka &#39;const char*&#39;} to &#39;LPCWSTR&#39; {aka &#39;const wchar_t*&#39;} 400 | UnregisterClassW(wc.lpszClassName, wc.hInstance); | ~~~^~~~~~~~~~~~~ | | | LPCSTR {aka const char*} In file included from D:/TDM/x86_64-w64-mingw32/include/Windows.h:72, from BasicStruct.hpp:2, from main.cpp:5: D:/TDM/x86_64-w64-mingw32/include/winuser.h:2152:55: note: initializing argument 1 of &#39;WINBOOL UnregisterClassW(LPCWSTR, HINSTANCE)&#39; 2152 | WINUSERAPI WINBOOL WINAPI UnregisterClassW (LPCWSTR lpClassName, HINSTANCE hInstance); | ~~~~~~~~^~~~~~~~~~~ main.cpp: In function &#39;void SimAimBot()&#39;: main.cpp:570:5: error: &#39;pow&#39; was not declared in this scope 570 | pow(shotat_players[i].Bones[2].x, 2) + | ^~~ main.cpp:569:18: error: &#39;sqrt&#39; was not declared in this scope 569 | distance[i] = sqrt( | ^~~~ main.cpp: In function &#39;void AimBot()&#39;: main.cpp:666:26: error: &#39;hypot&#39; is not a member of &#39;std&#39; 666 | const auto fov = std::hypot(angle.x, angle.y); | ^~~~~ main.cpp: In function &#39;int WinMain(HINSTANCE, HINSTANCE, LPSTR, int)&#39;: main.cpp:402:1: warning: control reaches end of non-void function [-Wreturn-type] 402 | } | ^ Cheats.cpp: In function &#39;BOOL bGetModBaseAddr(LPCWSTR, DWORD, DWORD64&amp;)&#39;: Cheats.cpp:56:30: error: cannot convert &#39;char*&#39; to &#39;LPCWSTR&#39; {aka &#39;const wchar_t*&#39;} 56 | if (!lstrcmpW(md.szModule, ModuleName)) { | ~~~^~~~~~~~ | | | char* In file included from D:/TDM/x86_64-w64-mingw32/include/Windows.h:70, from Cheats.h:2, from Cheats.cpp:1: D:/TDM/x86_64-w64-mingw32/include/winbase.h:1418:43: note: initializing argument 1 of &#39;int lstrcmpW(LPCWSTR, LPCWSTR)&#39; 1418 | WINBASEAPI int WINAPI lstrcmpW (LPCWSTR lpString1, LPCWSTR lpString2); | ~~~~~~~~^~~~~~~~~ Cheats.cpp: In function &#39;std::string unionToWide(char16_t)&#39;: Cheats.cpp:105:10: error: &#39;wstring_convert&#39; is not a member of &#39;std&#39; 105 | std::wstring_convert&lt;std::codecvt_utf8_utf16&lt;char16_t&gt;, char16_t&gt; convert; | ^~~~~~~~~~~~~~~ Cheats.cpp:105:59: error: expected primary-expression before &#39;,&#39; token 105 | std::wstring_convert&lt;std::codecvt_utf8_utf16&lt;char16_t&gt;, char16_t&gt; convert; | ^ Cheats.cpp:105:61: error: expected primary-expression before &#39;char16_t&#39; 105 | std::wstring_convert&lt;std::codecvt_utf8_utf16&lt;char16_t&gt;, char16_t&gt; convert; | ^~~~~~~~ Cheats.cpp:106:12: error: &#39;convert&#39; was not declared in this scope; did you mean &#39;connect&#39;? 106 | return convert.to_bytes(u16str); | ^~~~~~~ | connect Cheats.cpp: In function &#39;std::string GetPlayerName(HANDLE, DWORD64)&#39;: Cheats.cpp:113:19: warning: NULL used in arithmetic [-Wpointer-arith] 113 | if (dwBase == NULL) return &quot;&quot;; | ^~~~ Cheats.cpp: In constructor &#39;SelfPlayer::SelfPlayer(const Cheats&amp;)&#39;: Cheats.cpp:348:48: error: type &#39;Cheats&#39; is not a direct base of &#39;SelfPlayer&#39; 348 | SelfPlayer::SelfPlayer(const Cheats&amp; cheats) : Cheats(cheats) { | ^~~~~~ PS D:\ExtCheats-main\ExtCheats-main\ExtCheats&gt; 帮我修改一下
最新发布
09-19
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值