函數”: 無法將參數 n 從“類型 1”轉換爲“類型 2”
如果創建了某個類的實例,然後嘗試了對用 explicit 關鍵字標記的構造函數進行隱式轉換,則可能會發生此參數轉換問題。有關顯式轉換的詳細信息,請參閱轉換。
如果將臨時對象傳遞給採用指向對象的引用作爲參數的函數,則該引用必須是 const 引用。
如果使用不是函數所預期的類型的參數傳遞該函數,則使用適當的構造函數可創建臨時對象。然後將該臨時對象傳遞給函數。在這種情況下,該臨時對象用於初始化引用。在該語言的早期版本中,所有的引用都可以由臨時對象進行初始化。
若要修復 C2664,請執行以下操作
-
再次檢查給定函數的原型,並改正錯誤信息中指出的參數。
-
如果需要的話,提供顯式轉換。
如果某個類在它的一個基類中隱藏了成員,也可能生成 C2664。
有關詳細信息,請參閱如何:將 System::String 轉換爲 wchar_t* 或 char*。
下面的示例生成 C2664,並演示如何修復此錯誤。
// 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. }
此示例也生成 C2664,並演示如何修復此錯誤。
// 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. }
下一個示例通過使用字符串調用 Test 來演示 C2664,並演示如何修復此錯誤。因爲該參數是 szString 引用,所以必須使用適當的構造函數創建對象。結果是一個無法用於初始化該引用的臨時對象。
// 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"); }
編譯器強制實施應用 const 的 C++ 標準要求。此示例生成 C2664:
// C2664d.cpp // C2664 expected #include <windows.h> void func1(LPCSTR &s) { } void func2(LPSTR &s) { func1(s); } int main() { return 0; }
下面是生成 C2664 的更復雜情況,包括有關如何修復此錯誤的說明:
// 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); }
枚舉變量未轉換爲其滿足函數調用的基礎類型。有關詳細信息,請參閱 enum 類(C++ 組件擴展)。下面的示例生成 C2664,並演示如何修復此錯誤。
// 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 }
midl 編譯器中的 Bug 導致 wchar_t 類型作爲類型庫中的 unsigned short 發出。若要糾正此錯誤,請在 C++ 源代碼中強制轉換類型,或者在 idl 文件中將類型定義爲字符串。
// 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,並演示如何修復此錯誤。
// 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。
// 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 }
將代碼從 Visual C++ 6.0 移植到更高版本時,使用 wchar_t 也會引發 C2664。在 Visual C++ 6.0 和更早版本中,wchar_t 是 typedef 的unsigned short,因此也可隱式轉換爲該類型。在 Visual C++ 6.0 後,wchar_t 是它自己的內置類型(在 C++ 標準中指定),因此不再能隱式轉換爲 unsigned short。請參閱 /Zc:wchar_t(wchar_t 是本機類型)。