Bagikan melalui


Compiler Error C2664

'function' : tidak dapat mengonversi argumen n dari 'type1' ke 'type2'

Masalah konversi parameter ini mungkin terjadi jika instans kelas dibuat dan konversi implisit dicoba pada konstruktor yang ditandai dengan explicit kata kunci. Untuk informasi selengkapnya tentang konversi eksplisit, lihat Konversi Jenis yang Ditentukan Pengguna.

Jika objek sementara diteruskan ke fungsi yang mengambil referensi ke objek sebagai parameter, referensi tersebut harus menjadi const referensi.

Jika fungsi diteruskan parameter yang bukan dari jenis yang diharapkan fungsi, objek sementara dibuat dengan menggunakan konstruktor yang sesuai. Objek sementara ini kemudian diteruskan ke fungsi . Dalam hal ini, objek sementara digunakan untuk menginisialisasi referensi. Dalam versi bahasa yang lebih lama, semua referensi dapat diinisialisasi oleh objek sementara.

Untuk memperbaiki C2664,

  • Periksa ulang prototipe untuk fungsi yang diberikan dan perbaiki argumen yang dicatat dalam pesan kesalahan.

  • Berikan konversi eksplisit jika perlu.

C2664 juga dapat dihasilkan jika kelas menyembunyikan anggota di salah satu kelas dasarnya.

Untuk informasi selengkapnya, lihat Cara: Mengonversi Sistem::String ke wchar_t* atau karakter*.

Contoh

Sampel berikut menghasilkan C2664 dan menunjukkan cara memperbaikinya.

// 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.
}

Sampel ini juga menghasilkan C2664 dan menunjukkan cara memperbaikinya.

// 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.
}

Sampel berikutnya menunjukkan C2664 dengan menggunakan string literal untuk memanggil Test, dan menunjukkan cara memperbaikinya. Karena parameter adalah szString referensi, objek harus dibuat oleh konstruktor yang sesuai. Hasilnya adalah objek sementara yang tidak dapat digunakan untuk menginisialisasi referensi.

// 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");
}

Kompilator memberlakukan persyaratan standar C++ untuk menerapkan const. Sampel ini menghasilkan C2664:

// C2664d.cpp
// C2664 expected
#include <windows.h>

void func1(LPCSTR &s)
{

}

void func2(LPSTR &s)
{
   func1(s);
}

int main()
{
   return 0;
}

Berikut adalah situasi yang lebih kompleks di mana C2664 dihasilkan, termasuk petunjuk tentang cara memperbaikinya:

// 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);
}

Variabel enum tidak dikonversi ke jenis yang mendasarnya sedemikian rupa sehingga panggilan fungsi akan terpenuhi. Untuk informasi selengkapnya, lihat kelas enum. Sampel berikut menghasilkan C2664 dan menunjukkan cara memperbaikinya.

// 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
}

Bug di kompilator midl menyebabkan jenis wchar_t dipancarkan sebagai pendek yang tidak ditandatangani di pustaka jenis. Untuk mengatasi kesalahan ini, transmisikan jenis dalam kode sumber C++ Anda atau tentukan jenis sebagai string dalam file 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 juga dinaikkan dengan menggunakan wchar_t saat porting code dari Visual C++ 6.0 ke versi yang lebih baru. Di Visual C++ 6.0 dan yang lebih lama, wchar_t adalah typedef untuk unsigned short dan oleh karena itu secara implisit dapat dikonversi ke jenis tersebut. Setelah Visual C++ 6.0, wchar_t adalah jenis bawaannya sendiri, seperti yang ditentukan dalam standar C++, dan tidak lagi secara implisit dapat dikonversi ke unsigned short. Lihat /Zc:wchar_t (wchar_t Jenis Asli).

Sampel berikut menghasilkan C2664 dan menunjukkan cara memperbaikinya.

// 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 juga disebabkan jika pengkompilasi tidak dapat menyimpulkan argumen templat.

// 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
}