description | title | ms.date | f1_keywords | helpviewer_keywords | ms.assetid |
---|---|---|---|---|---|
Learn more about: Compiler Error C2664 |
Compiler Error C2664 |
11/04/2016 |
C2664 |
C2664 |
3595d66e-cf87-4fda-a896-c0cd81f95db4 |
Compiler Error C2664
‘function’ : cannot convert argument n from ‘type1’ to ‘type2’
This parameter conversion problem might happen if an instance of a class is created and an implicit conversion is attempted on a constructor marked with the explicit
keyword. For more information about explicit conversions, see User-Defined Type Conversions.
If a temporary object is passed to a function that takes a reference to an object as a parameter, that reference must be a const
reference.
If the function is passed a parameter that is not of the type that the function expects, a temporary object is created by using the appropriate constructor. This temporary object is then passed to the function. In this case, the temporary object is used to initialize the reference. In earlier versions of the language, all references could be initialized by temporary objects.
To fix C2664,
-
Recheck the prototype for the given function and correct the argument noted in the error message.
-
Supply an explicit conversion if necessary.
C2664 can also be generated if a class hides a member in one of its base classes.
For more information, see How to: Convert System::String to wchar_t* or char*.
Examples
The following sample generates C2664 and shows how to fix it.
// C2664.cpp // C2664 struct A { void f(int i) {}; }; struct B : public A { // To fix, uncomment the following line. // using A::f; void f(A a) {}; }; int main() { B b; int i = 1; b.f(i); // B::f hides A::f Uncomment the using declaration in B. }
This sample also generates C2664 and shows how to fix it.
// C2664b.cpp // C2664 expected struct A { // To fix, uncomment the following line. // A(int i){} }; void func( int, A ) {} int main() { func( 1, 1 ); // No conversion from int to A. }
The next sample demonstrates C2664 by using a string literal to call Test
, and shows how to fix it. Because the parameter is an szString
reference, an object must be created by the appropriate constructor. The result is a temporary object that cannot be used to initialize the reference.
// C2664c.cpp // compile with: /EHsc // C2664 expected #include <iostream> #include <string.h> using namespace std; class szString { int slen; char *str; public: szString(const char *); int len() const { return slen; } }; // Simple reference cannot bind to temp var. void Test(szString &a) {} // To fix, uncomment the following line. // void Test(const szString &a) {} szString::szString(const char * newstr) : slen(0), str(NULL) { slen=strlen(newstr); str = new char[slen + 1]; if (str) strcpy_s(str, (slen + 1), newstr); } int main() { Test("hello"); }
The compiler enforces the C++ standard requirements for applying const
. This sample generates C2664:
// C2664d.cpp // C2664 expected #include <windows.h> void func1(LPCSTR &s) { } void func2(LPSTR &s) { func1(s); } int main() { return 0; }
Here’s a more complex situation where C2664 is generated, including directions on how to fix it:
// C2664e.cpp // compile with: /EHsc // C2664 expected #define _INTL #include <locale> #include <iostream> using namespace std; #define LEN 90 int main( ) { char* pszExt = "This is the string to be converted!"; wchar_t pwszInt [LEN+1]; memset(&pwszInt[0], 0, (sizeof(wchar_t))*(LEN+1)); // To fix, delete the following line. char* pszNext; // To fix, uncomment the following line. // const char* pszNext; wchar_t* pwszNext; mbstate_t state; locale loc("C"); int res = use_facet<codecvt<wchar_t, char, mbstate_t> > ( loc ).in( state, pszExt, &pszExt[strlen(pszExt)], pszNext, pwszInt, &pwszInt[strlen(pszExt)], pwszNext ); // See earlier comment. pwszInt[strlen(pszExt)] = 0; wcout << ( (res!=codecvt_base::error) ? L"It worked! " : L"It didn't work! " ) << L"The converted string is:n [" << &pwszInt[0] << L"]" << endl; exit(-1); }
An enum variable is not converted to its underlying type such that a function call will be satisfied. For more information, see enum class. The following sample generates C2664 and shows how to fix it.
// C2664f.cpp // compile with: /clr using namespace System; public enum class A : Char { None = 0, NonSilent = 1, }; void Test(Char c) {} int main() { A aa = A::None; Test(aa); // C2664 Test(Char(aa)); // OK - fix by using a conversion cast }
A bug in the midl compiler causes a wchar_t type to be emitted as an unsigned short in the type library. To resolve this error, either cast the type in your C++ source code or define the type as a string in the idl file.
// C2664g.idl
import "prsht.idl";
[ object, uuid(8402B8F1-BF7F-4B49-92D4-C2B9DF4543E9) ]
interface IMyObj1 : IUnknown {
HRESULT teststr([in, string] wchar_t *wstr);
HRESULT testarr([in, size_is(len)] wchar_t wstr[], [in] int len);
HRESULT testbstr([in] BSTR bstr);
};
[ uuid(44463307-CBFC-47A6-8B4F-13CD0A83B436) ]
library myproj1 {
[ version(1.0), uuid(D8622C12-5448-42B8-8F0E-E3AD6B8470C1) ]
coclass CMyObj1 { interface IMyObj1; };
}
C2664 is also raised by using wchar_t
when porting code from Visual C++ 6.0 to later versions. In Visual C++ 6.0 and earlier, wchar_t
was a typedef
for unsigned short
and was therefore implicitly convertible to that type. After Visual C++ 6.0, wchar_t
is its own built-in type, as specified in the C++ standard, and is no longer implicitly convertible to unsigned short
. See /Zc:wchar_t (wchar_t Is Native Type).
The following sample generates C2664 and shows how to fix it.
// C2664h.cpp #import "C2664g.tlb" using namespace myproj1; int main() { IMyObj1Ptr ptr; wchar_t * mybuff = 0; BSTR bstr = 0; int len; ptr->teststr(mybuff); ptr->testbstr(bstr); ptr->testarr(mybuff, len); // C2664 ptr->testarr((unsigned short *)mybuff, len); // OK - Fix by using a cast }
C2664 is also caused if the compiler cannot deduce template arguments.
// C2664i.cpp #include <stdio.h> template <class T, int iType=0> class CTypedImg { public: CTypedImg() {} void run() {} operator CTypedImg<T>& () { return *((CTypedImg<T>*)this); } }; template <class t1> void test(CTypedImg<t1>& myarg) { myarg.run(); } int main() { CTypedImg<float,2> img; test((CTypedImg<float>&)img); // OK test<float>(img); // OK test(img); // C2664 - qualify as above to fix }
- Remove From My Forums
-
Question
-
Hi, I’m kinda new to Visual C++ and I’ve been studying with books and tutorials about Windows Apps and OpenGL, and I’ve been across this error quite often:
«Error C2664: ‘SomeLine’: Cannot convert parameter X from ‘const char[Y]’ to ‘LPCWSTR’ «.
I’ve seen somewhere that adding L to the begin of the string solves it (string myMessage = L»This is my string»; ) but I can’t do something like «TextOut(hDC, 150, 150, myMessage, sizeof(myMessage)-1) » — I get an «illegal sizeof operand».
And this happens on pretty much all the strings I work with, is there a way that I can «fix» this in a more practical way?
Answers
-
-
Marked as answer by
Thursday, June 4, 2009 4:32 PM
-
Marked as answer by
-
If the books and tutorials you are studying use ‘char’ and std::string they are not unicode compatible. But the default setting for Visual C++ projects is to use unicode.
For compatibility with char and std::string tutorials change you project properties Configuration, General, Character Set setting from unicode to Multi-Byte. Or for compatibility with Window’s unicode standard change your code — use TCHAR or wchar_t instead of char, use wstring instead of string, and prepend all constant strings with L.
-
Marked as answer by
DanCoelho
Thursday, June 4, 2009 4:31 PM
-
Marked as answer by
Иногда можно встретить вопросы об странных ошибках, выдаваемых компилятором при сборке 64-битного кода.
Вопрос может выглядеть следующим образом:
//Объявление класса
class Type1 {...};
class Type2 {...};
class A
{
public:
...
void Func1(Type1* t1.....);
void Func1(Type2& t2.....);
...
};
//Использование функции Func1
A obj;
Type2 t2;
...
obj.Func1(t2,...);
...
Данный код успешно компилировался в 32-битном режиме, но при попытке собрать 64-битную версию компилятор выдает ошибку C2664 (не может привести Type2 к Type1*). Определена функция, которая принимает Type2& в качестве аргумента, но компилятор почему-то пытается подставить функцию, принимающую Type1* в качестве параметра. В чем может быть проблема?
Скорее всего, дело в других параметрах, которые в примере были заменены точками. Рассмотрим следующий код:
class Type1 {};
class Type2 {};
class A
{
public:
void Func1(Type1* t1, unsigned &);
void Func1(Type2& t2, size_t &);
};
void use() {
A obj;
Type2 t2;
unsigned u;
obj.Func1(t2, u);
}
Он успешно компилируется в 32-битном режиме. Но в 64-битном обе функции не подходят. Компилятор принимает решение, что первая функция является лучшим кандидатом, так как у нее точно совпадает второй параметр. И сообщает, что не подходит первый аргумент: error C2664: ‘void A::Func1(Type1 *,unsigned int &)’ : cannot convert parameter 1 from ‘Type2’ to ‘Type1 *’. Решение — внимательно изучить остальные аргументы и внести в код необходимые изменния.
Присылаем лучшие статьи раз в месяц
Vasiliyy 4 / 3 / 6 Регистрация: 13.11.2015 Сообщений: 217 |
||||||||||||||||
1 |
||||||||||||||||
14.04.2016, 00:05. Показов 4961. Ответов 13 Метки нет (Все метки)
При компиляции выскочили следующие ошибки: Кликните здесь для просмотра всего текста
38 строка: Кликните здесь для просмотра всего текста
191 строка: Кликните здесь для просмотра всего текста
56 строка = 57 и 58 строки: Кликните здесь для просмотра всего текста
Помогите исправить это пожалуйста.
__________________
0 |
7275 / 6220 / 2833 Регистрация: 14.04.2014 Сообщений: 26,871 |
|
14.04.2016, 09:17 |
2 |
Соглашение о вызове не совпадает. _beginthread() ожидает cdecl, а ты передаёшь stdcall.
1 |
4 / 3 / 6 Регистрация: 13.11.2015 Сообщений: 217 |
|
14.04.2016, 23:02 [ТС] |
3 |
up.
0 |
7275 / 6220 / 2833 Регистрация: 14.04.2014 Сообщений: 26,871 |
|
14.04.2016, 23:26 |
4 |
Ты исправил?
0 |
Vasiliyy 4 / 3 / 6 Регистрация: 13.11.2015 Сообщений: 217 |
||||
15.04.2016, 01:26 [ТС] |
5 |
|||
nmcf, нет, не пойму где это исправлять надо, функции _beginthread нет ни в каком файле. Добавлено через 9 минут
0 |
7275 / 6220 / 2833 Регистрация: 14.04.2014 Сообщений: 26,871 |
|
15.04.2016, 08:45 |
6 |
reconnectThread() и mainThread() как объявлены? Сделай, чтобы они __cdecl были.
0 |
16495 / 8988 / 2205 Регистрация: 30.01.2014 Сообщений: 15,611 |
|
15.04.2016, 10:14 |
7 |
Это что за библиотека вообще? Это CRT API Винды. Функции для создания потока. По теме: автор, не надо сюда постить библиотечный код. Пости свой.
0 |
Vasiliyy 4 / 3 / 6 Регистрация: 13.11.2015 Сообщений: 217 |
||||
18.04.2016, 14:07 [ТС] |
8 |
|||
DrOffset,
Объявления своих функций mainThread и reconnectThread покажи.
reconnectThread не нужно.
0 |
nmcf 7275 / 6220 / 2833 Регистрация: 14.04.2014 Сообщений: 26,871 |
||||
18.04.2016, 14:22 |
9 |
|||
Сообщение было отмечено Vasiliyy как решение РешениеА так?
1 |
4 / 3 / 6 Регистрация: 13.11.2015 Сообщений: 217 |
|
18.04.2016, 15:22 [ТС] |
10 |
nmcf, да спасибо, скомпилировалось, но при проверке через пару сек — краш. Буду выяснять как исправить
0 |
7275 / 6220 / 2833 Регистрация: 14.04.2014 Сообщений: 26,871 |
|
18.04.2016, 15:30 |
11 |
Ну дело уже не в _beginthread(), значит.
0 |
Vasiliyy 4 / 3 / 6 Регистрация: 13.11.2015 Сообщений: 217 |
||||
18.04.2016, 15:46 [ТС] |
12 |
|||
nmcf, такое было в одном плагине, и я весь его состав перекидаю в другой. Я выяснил причину краша, тут не выполняется условие:
Так вот в логах часто пишется «tryInit(void)» и «g_SAMP == nullptr», значит это условие не выполняется. Как исправить это?
0 |
7275 / 6220 / 2833 Регистрация: 14.04.2014 Сообщений: 26,871 |
|
18.04.2016, 16:05 |
13 |
dwSAMPAddr надо смотреть, наверное.
0 |
Vasiliyy 4 / 3 / 6 Регистрация: 13.11.2015 Сообщений: 217 |
||||
18.04.2016, 17:27 [ТС] |
14 |
|||
nmcf,
вот так, не дописал dwSAMPAddr просто.
0 |