Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
"inicializálás": nem konvertálható a "type1" típusról "type2" típusra
"átalakítás" : nem konvertálható a "type1" típusról "type2" típusra
Megjegyzések
A fordító nem tud implicit módon konvertálni type1-ról type2-ra, vagy nem használhatja a megadott kaszt vagy konverziós operátort.
A fordító akkor hozza létre a C2440-et, ha nem tud áttérni egyik típusról a másikra implicit módon, vagy a megadott öntött vagy konverziós operátor használatával. Ezt a hibát többféleképpen is létrehozhatja. Néhány gyakoriat a Példák szakaszban soroltunk fel.
Példák
A C++ sztringkonstansok a következők: const
A C2440 akkor fordulhat elő, ha C++ kódban egy szó szerinti karakterlánc használatával próbál inicializálni egy nem-constchar* (vagy wchar_t*) értéket, amikor be van állítva a fordító megfelelőségi opciója /Zc:strictStrings. A C-ben a sztringkonstans típusa karaktertömb char, a C++-ban azonban karaktertömb const char. Ez a példa c2440-et hoz létre:
// 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
}
A C++20 u8 literálok const char8_t
A C++20 vagy korábbi verziókban /Zc:char8_t egy UTF-8 literális karakter vagy sztring (például u8'a' vagy u8"String") típusa const char8_t vagy const char8_t[N]. Ez a példa bemutatja, hogyan változik a fordító viselkedése a C++17 és a C++20 között:
// 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
}
Mutató a tagra
A C2440 akkor jelenhet meg, ha megpróbál egy mutatót tagmutatóvá alakítani, hogy void* legyen. A következő példa a C2440-et hozza létre:
// 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);
}
};
Nem definiált típusú értékátalakítás
A fordító C2440-et bocsát ki, ha olyan típusból próbál átalakítani, amely csak előre deklarált, de nem definiált. Ez a példa c2440-et hoz létre:
// 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 *'
}
Inkompatibilis hívási konvenció
A következő példa 15. és 16. sorában szereplő C2440-hibák az Incompatible calling conventions for UDT return value üzenettel vannak minősítve. Az UDT egy felhasználó által definiált típus, például osztály structvagy egyesítő. Az ilyen típusú inkompatibilitási hibák akkor keletkeznek, ha egy előre deklaráció visszatérési típusában megadott UDT hívási konvenciója ütközik az UDT tényleges hívási konvenciójával, és ha függvénymutatót használ.
A példában először szerepelnek előre deklarációk egy struct-hez és egy függvényhez, amely visszaadja a struct-t. A fordító feltételezi, hogy a struct C++ hívási konvenciót használja. A következő a struct definíció, amely alapértelmezés szerint a C hívási konvenciót használja. Mivel a fordító nem ismeri a struct hívási konvencióját, amíg be nem fejezi a teljes struct olvasását, a struct visszatérési típusának get_c2 hívási konvenciója is C++-nak tekintendő.
A struct-t követi egy másik függvénydeklaráció, amely visszaadja a struct-et. Ezen a ponton a fordító tudja, hogy a structhívási konvenció C++. Hasonlóképpen, a függvénymutató, amely a függvényt structadja vissza, a struct definíció után van definiálva. A fordító már tudja, hogy a struct C++ hívási konvenciót használja.
Az inkompatibilis hívási konvenciók által okozott C2440-hibák megoldásához deklarálja az UDT-t visszaadó függvényeket az UDT-definíció után.
// 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
}
A belső mutató nullára állítása
A C2440 akkor is előfordulhat, ha nullát rendel egy belső mutatóhoz:
// 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
}
Felhasználó által definiált konverziók
A C2440 a felhasználó által definiált átalakítás helytelen használata esetén is előfordulhat. Ha például egy konverziós operátort explicit definiáltak, a fordító nem használhatja azt implicit konverzióban. További információ a felhasználó által definiált konverziókról: User-Defined Konverziók (C++/CLI)). Ez a példa c2440-et hoz létre:
// 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 alkotás
A C2440 akkor is előfordulhat, ha olyan tömbpéldányt próbál létrehozni a C++/CLI-ben, amelynek típusa egy Array. További információ: Tömbök. A következő példa a C2440-et hozza létre:
// 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));
}
Tulajdonságok
A C2440 az attribútumok funkció változásai miatt is előfordulhat. Az alábbi példa C2440-et hoz létre.
// c2440f.cpp
// compile with: /LD
[ module(name="PropDemoLib", version=1.0) ]; // C2440
// try the following line instead
// [ module(name="PropDemoLib", version="1.0") ];
Az összetevő-bővítmények lefelé történő kasztolása
A Microsoft C++ fordító már nem teszi lehetővé a const_cast operátor számára, hogy leszármaztást végezzen, amikor a forráskódot /clr alatt fordítják.
A C2440 feloldásához használja a megfelelő típuskonverziós operátort. További információ: Kasztolási operátorok.
Ez a példa c2440-et hoz létre:
// 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
}
A megfelelő sablon egyezik a módosításokkal
A C2440 a Visual Studio 2015 3. frissítésében a fordító megfelelőségi változásai miatt fordulhat elő. Korábban a fordító helytelenül kezelt bizonyos különálló kifejezéseket ugyanolyan típusúként, amikor egy sablon egyezést keresett egy static_cast művelethez. Most a fordító megfelelően megkülönbözteti a típusokat, és az előző static_cast viselkedésre támaszkodó kód hibás. A probléma megoldásához módosítsa a sablon argumentumát úgy, hogy megfeleljen a sablonparaméter típusának, vagy használjon egy `reinterpret_cast` vagy C stílusú típuskonverziót.
Ez a példa c2440-et hoz létre:
// 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);
}
Ez a hiba a következőben definiált makrót SINK_ENTRY_INFO használó ATL-kódban <atlcom.h>jelenhet meg:
Másolási lista inicializálása
A Visual Studio 2017 és újabb verziói helyesen jelzik az objektumlétrehozáskor előforduló fordítóhibákat az inicializáló listák használatával. Ezeket a hibákat a Visual Studio 2015 nem észlelte, és összeomlásokhoz vagy nem definiált futtatókörnyezeti viselkedéshez vezethet. A C++17 másolási lista inicializálása során a fordítónak explicit konstruktort kell figyelembe vennie a túlterhelés feloldásához, de hibát kell okoznia, ha a túlterhelést ténylegesen választja.
Az alábbi példa a Visual Studio 2015-ben készült, de a Visual Studio 2017-ben nem.
// 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 &'
}
A hiba kijavításához használja a közvetlen inicializálást:
// C2440k.cpp
struct A
{
explicit A(int) {}
A(double) {}
};
int main()
{
const A& a2{ 1 };
}
cv-qualifikátorok az osztályépítésben
A Visual Studio 2015-ben a fordító néha helytelenül figyelmen kívül hagyja a cv-minősítőt, amikor egy osztályobjektumot konstruktorhíváson keresztül hoz létre. Ez a hiba összeomlást vagy váratlan futtatókörnyezeti működést okozhat. Az alábbi példa a Visual Studio 2015-ben fordít, de fordítói hibát jelez a Visual Studio 2017-ben és újabb verzióiban:
struct S
{
S(int);
operator int();
};
int i = (const S)0; // error C2440
A hiba kijavításához deklarálja az int() operátort.const