Błąd kompilatora C2664

'funkcja' : nie można konwertować numeru parametru z 'type1' na 'type2'

Ten problem z parametrem konwersji może się zdarzyć, gdy tworzone jest wystąpienie klasy i w odniesieniu do konstruktora oznaczona za pomocą próbie niejawna explicit słowo kluczowe.Aby uzyskać więcej informacji na temat Konwersje jawne zobacz Konwersje.

Jeśli obiekt tymczasowy jest przekazywany do funkcji, która przyjmuje odwołanie do obiektu jako parametr, to odwołanie musi być odwołaniem const.

Jeśli do funkcji jest przekazywany parametr, który jest typu innego niż ten, którego oczekuje funkcja, tymczasowy obiekt jest tworzony za pomocą odpowiedniego konstruktora.Ten tymczasowy obiekt jest następnie przekazywany do funkcji.W tym przypadku tymczasowy obiekt jest używany do zainicjowania odwołania.We wcześniejszych wersjach języka wszystkie odwołania można było zainicjować przez obiekty tymczasowe.

Aby rozwiązać C2664,

  • Sprawdź ponownie prototyp dla danej funkcji i popraw argument wymieniony w komunikacie o błędzie.

  • Jeśli to konieczne, podaj konwersję jawną.

C2664 może być też wygenerowany, jeśli klasa ukrywa element członkowski w jednej z jej klas podstawowych.

Aby uzyskać więcej informacji, zobacz Porady: konwertowanie obiektu System::String na ciąg wchar_t* lub char*.

Przykład

Poniższy przykład spowoduje wygenerowanie błędu C2664.

// C2664.cpp
// C2664 
struct A {
   void f(int i) {};
};

struct B : public A {
   // To resolve, 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.
}

Ten przykład również generuje C2664.

// C2664b.cpp
// C2664 expected
struct A {
   // To resolve, uncomment the following line.
   // A(int i){}
};

void func( int, A ) {}

int main() {
   func( 1, 1 );   // No conversion from int to A.
}

Następny przykład ilustruje C2664 poprzez użycie literału ciągu znaków do wywołania Test.Ponieważ ten parametr jest odwołaniem szString, obiekt musi być utworzony przez odpowiedni konstruktor.W wyniku powstaje tymczasowy obiekt, którego nie można użyć do zainicjowania odwołania.

// 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 resolve, 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 wymusza standardowe wymagania C++ dotyczące stosowania const.Ten przykład generuje C2664:

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

void func1(LPCSTR &s)
{

}

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

int main()
{
   return 0;
}

Oto bardziej złożona sytuacja, w której jest generowany 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 resolve, delete the following line.
   char* pszNext;

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

Zmienna enum nie jest konwertowana na jej typ podstawowy, tak aby wywołanie funkcji zostało spełnione.Aby uzyskać więcej informacji, zobacz Wylicz klasy.Poniższy przykład spowoduje wygenerowanie błędu 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
}

Błąd w kompilatorze midl powoduje, że typ wchar_t jest emitowany jako short bez znaku w bibliotece typów.Aby wyeliminować ten błąd, rzutuj typ w kodzie źródłowym C++ lub zdefiniuj typ jako ciąg w pliku 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 jest także generowany przez stosowanie wchar_t podczas przenoszenia kodu z Visual C++ 6.0 do nowszych wersji.W Visual C++ 6.0 i starszych wchar_t był typedef dla unsigned short i dlatego został niejawnie skonwertowany na ten typ.W wersjach nowszych niż Visual C++ 6.0 wchar_t jest własnym wbudowanym typem, jak określono w standardzie C++, i nie jest już niejawnie konwertowany na unsigned short.Zobacz /Zc:wchar_t (wchar_t jest typem natywnym).

Poniższy przykład spowoduje wygenerowanie błędu 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
}

Jeśli kompilator nie może wywnioskować argumentów szablonu, również jest generowany 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
}