Not
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
"initializing" : kan inte konvertera från 'type1' till 'type2'
"konvertering" : kan inte konvertera från "type1" till "type2"
Anmärkningar
Kompilatorn kan inte implicit konvertera från type1 till type2eller kan inte använda den angivna cast- eller konverteringsoperatorn.
Kompilatorn genererar C2440 när den inte kan konvertera från en typ till en annan, antingen implicit eller med hjälp av den angivna cast- eller konverteringsoperatorn. Det finns många sätt att generera det här felet. Vi har listat några vanliga i avsnittet Exempel.
Exempel
C++-strängliteraler är const
C2440 kan orsakas om du försöker initiera en icke-constchar* (eller wchar_t*) med hjälp av en strängliteral i C++-kod när kompilatorkonformitetsalternativet /Zc:strictStrings har angetts. I C är typen av en strängliteral matris av char, men i C++ är det matris av const char. Det här exemplet genererar C2440:
// C2440s.cpp
// Build: cl /Zc:strictStrings /W3 C2440s.cpp
// When built, the compiler emits:
// error C2440: 'initializing' : cannot convert from 'const char [5]'
// to 'char *'
// Conversion from string literal loses const qualifier (see
// /Zc:strictStrings)
int main() {
char* s1 = "test"; // C2440
const char* s2 = "test"; // OK
}
C++20-literaler u8 är const char8_t
I C++20 eller under /Zc:char8_tär ett UTF-8-literaltecken eller sträng (till exempel u8'a' eller u8"String") av typen const char8_t eller const char8_t[N]. Det här exemplet visar hur kompilatorbeteendet ändras mellan C++17 och C++20:
// C2440u8.cpp
// Build: cl /std:c++20 C2440u8.cpp
// When built, the compiler emits:
// error C2440: 'initializing' : cannot convert from 'const char8_t [5]'
// to 'const char *'
// note: Types pointed to are unrelated; conversion requires
// reinterpret_cast, C-style cast or function-style cast)
int main() {
const char* s1 = u8"test"; // C2440 under /std:c++20 or /Zc:char8_t, OK in C++17
const char8_t* s2 = u8"test"; // OK under /std:c++20 or /Zc:char8_t, C4430 in C++17
const char* s3 = reinterpret_cast<const char*>(u8"test"); // OK
}
Pekare till medlem
Du kan se C2440 om du försöker konvertera en pekare till medlem till void*. Nästa exempel genererar C2440:
// C2440.cpp
class B {
public:
void f(){;}
typedef void (B::*pf)();
void f2(pf pf) {
(this->*pf)();
void* pp = (void*)pf; // C2440
}
void f3() {
f2(f);
}
};
Gjutning av odefinierad typ
Kompilatorn genererar C2440 om du försöker konvertera från en typ som endast är förklarad i förväg men inte definierad. Det här exemplet genererar C2440:
// c2440a.cpp
struct Base { }; // Defined
struct Derived; // Forward declaration, not defined
Base * func(Derived * d) {
return static_cast<Base *>(d); // error C2440: 'static_cast' : cannot convert from 'Derived *' to 'Base *'
}
Inkompatibel samtalskonvention
C2440-felen på raderna 15 och 16 i nästa exempel är kvalificerade med meddelandet Incompatible calling conventions for UDT return value . En UDT är en användardefinierad typ, till exempel en klass, structeller union. Den här typen av inkompatibilitetsfel orsakas när anropskonventionen för en UDT som anges i returtypen för en framåtdeklaration står i konflikt med UDT:s faktiska anropskonvention och när en funktionspekare ingår.
I exemplet finns det först framåtdeklarationer för en struct och för en funktion som returnerar struct. Kompilatorn förutsätter att struct använder C++-anropskonventionen. Nästa är struct definitionen, som använder C-anropskonventionen som standard. Eftersom kompilatorn inte känner till anropskonventionen struct förrän den har läst klart hela structantas anropskonventionen för struct i returtypen get_c2 också vara C++.
struct Följs av en annan funktionsdeklaration som returnerar struct. Nu vet kompilatorn att structanropskonventionen är C++. På samma sätt definieras funktionspekaren, som returnerar struct, efter struct definitionen. Kompilatorn känner nu till struct användningskonventionen för C++-anrop.
För att lösa C2440-fel som orsakas av inkompatibla anropskonventioner deklarerar du funktioner som returnerar en UDT efter UDT-definitionen.
// C2440b.cpp
struct MyStruct;
MyStruct get_c1();
struct MyStruct {
int i;
static MyStruct get_C2();
};
MyStruct get_C3();
typedef MyStruct (*FC)();
FC fc1 = &get_c1; // C2440, line 15
FC fc2 = &MyStruct::get_C2; // C2440, line 16
FC fc3 = &get_C3;
class CMyClass {
public:
explicit CMyClass( int iBar)
throw() {
}
static CMyClass get_c2();
};
int main() {
CMyClass myclass = 2; // C2440
// try one of the following
// CMyClass myclass{2};
// CMyClass myclass(2);
int *i;
float j;
j = (float)i; // C2440, cannot cast from pointer to int to float
}
Tilldela noll till inre pekare
C2440 kan också inträffa om du tilldelar noll till en inre pekare:
// C2440c.cpp
// compile with: /clr
int main() {
array<int>^ arr = gcnew array<int>(100);
interior_ptr<int> ipi = &arr[0];
ipi = 0; // C2440
ipi = nullptr; // OK
}
Användardefinierade konverteringar
C2440 kan också inträffa vid felaktig användning av en användardefinierad konvertering. När en konverteringsoperator till exempel har definierats som explicitkan kompilatorn inte använda den i en implicit konvertering. Mer information om användardefinierade konverteringar finns iUser-Defined Konverteringar (C++/CLI)). Det här exemplet genererar C2440:
// C2440d.cpp
// compile with: /clr
value struct MyDouble {
double d;
// convert MyDouble to Int32
static explicit operator System::Int32 ( MyDouble val ) {
return (int)val.d;
}
};
int main() {
MyDouble d;
int i;
i = d; // C2440
// Uncomment the following line to resolve.
// i = static_cast<int>(d);
}
System::Array skapelse
C2440 kan också inträffa om du försöker skapa en instans av en matris i C++/CLI vars typ är en Array. Mer information finns i Matriser. Nästa exempel genererar C2440:
// C2440e.cpp
// compile with: /clr
using namespace System;
int main() {
array<int>^ intArray = Array::CreateInstance(__typeof(int), 1); // C2440
// try the following line instead
// array<int>^ intArray = safe_cast<array<int> ^>(Array::CreateInstance(__typeof(int), 1));
}
Egenskaper
C2440 kan också inträffa på grund av ändringar i attributfunktionen. I följande exempel genereras C2440.
// c2440f.cpp
// compile with: /LD
[ module(name="PropDemoLib", version=1.0) ]; // C2440
// try the following line instead
// [ module(name="PropDemoLib", version="1.0") ];
Komponenttillägg nedtypekonverteringar
Microsoft C++-kompilatorn tillåter inte längre att operatornconst_cast gör en downcast när du kompilerar källkoden under /clr.
Lös denna C2440 genom att använda rätt gjutningsoperator. För mer information, se Castingoperatorer.
Det här exemplet genererar C2440:
// c2440g.cpp
// compile with: /clr
ref class Base {};
ref class Derived : public Base {};
int main() {
Derived ^d = gcnew Derived;
Base ^b = d;
d = const_cast<Derived^>(b); // C2440
d = dynamic_cast<Derived^>(b); // OK
}
Ändringar för att anpassa mallmatchning
C2440 kan inträffa på grund av överensstämmelseändringar i kompilatorn i Visual Studio 2015 Update 3. Tidigare behandlade kompilatorn felaktigt vissa distinkta uttryck som samma typ när en mallmatchning identifierades för en static_cast åtgärd. Nu särskiljer kompilatorn typerna korrekt och koden som förlitade sig på det tidigare static_cast beteendet är bruten. Åtgärda problemet genom att ändra mallargumentet så att det matchar mallparametertypen, eller använda en reinterpret_cast eller C-formatering.
Det här exemplet genererar C2440:
// c2440h.cpp
template<int *a>
struct S1 {};
int g;
struct S2 : S1<&g> {
};
int main()
{
S2 s;
static_cast<S1<&*&g>>(s); // C2440 in VS 2015 Update 3
// This compiles correctly:
// static_cast<S1<&g>>(s);
}
Det här felet kan visas i ATL-kod som använder makrot SINK_ENTRY_INFO som definierats i <atlcom.h>.
Kopieringsbaserad listinitiering
Visual Studio 2017 och senare skapar kompilatorfel som är relaterade till att skapa objekt med hjälp av initialiserarlistor. Dessa fel fångades inte i Visual Studio 2015 och kan leda till krascher eller odefinierat körningsbeteende. I C++17 copy-list-initialization måste kompilatorn beakta en explicit konstruktor vid överbelastningslösning, men den måste generera ett fel om den överbelastningen verkligen väljs.
Följande exempel kompileras i Visual Studio 2015 men inte i Visual Studio 2017.
// C2440j.cpp
struct A
{
explicit A(int) {}
A(double) {}
};
int main()
{
const A& a2 = { 1 }; // error C2440: 'initializing': cannot
// convert from 'int' to 'const A &'
}
Du kan åtgärda felet genom att använda direktinitiering:
// C2440k.cpp
struct A
{
explicit A(int) {}
A(double) {}
};
int main()
{
const A& a2{ 1 };
}
cv-kvalificerare i klasskonstruktion
I Visual Studio 2015 ignorerar kompilatorn ibland felaktigt cv-qualifier när ett klassobjekt genereras via ett konstruktoranrop. Den här defekten kan potentiellt orsaka en krasch eller oväntat körningsbeteende. Följande exempel kompileras i Visual Studio 2015 men skapar ett kompilatorfel i Visual Studio 2017 och senare:
struct S
{
S(int);
operator int();
};
int i = (const S)0; // error C2440
Om du vill korrigera felet deklarerar du operatorn int() som const.