共用方式為


編譯器錯誤 C2440

' initializing ' : 無法從 ' type1 ' 轉換為 ' type2 '
' conversion ' : 無法從 ' type1 ' 轉換為 ' type2 '

編譯器無法隱含地從 *type1* 轉換為 *type2* ,或無法使用指定的轉換或轉換運算子。

備註

編譯器會在無法從某個型別轉換為另一種類型時,隱含地或使用指定的轉換運算子來產生 C2440。 有許多方法可以產生此錯誤。 我們已在 一節中列出一些常見的範例。

範例

C++ 字串常值為 const

如果您在設定編譯器一致性選項 /Zc:strictStrings 時,嘗試在 C++ 程式碼中使用字串常值來初始化非 constchar* (或 wchar_t* ) ,可能會造成 C2440。 在 C 中,字串常值的類型是 的 char 陣列,但在 C++ 中,它是 的 const char 陣列。 此範例會產生 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 u8 常值為 const char8_t

在 C++20 或下 /Zc:char8_t ,UTF-8 常值字元或字串 (例如 u8'a'u8"String" ) 分別屬於 或 const char8_t[N] 類型 const char8_t 或 。 此範例示範編譯器行為如何變更 C++17 和 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
}

成員的指標

如果您嘗試將指標轉換成 成員 void* ,您可能會看到 C2440。 下一個範例會產生 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);
   }
};

未定義型別的轉換

如果您嘗試從只宣告但未定義的類型轉換,編譯器會發出 C2440。 此範例會產生 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 *'
}

不相容的呼叫慣例

下一個範例第 15 行和第 16 行的 C2440 錯誤會以 Incompatible calling conventions for UDT return value 訊息限定。 UDT 是使用者定義的類型,例如類別、 struct 或等位。 當轉送宣告傳回類型中指定的 UDT 呼叫慣例與 UDT 的實際呼叫慣例衝突,以及涉及函式指標時,就會造成這類不相容錯誤。

在此範例中,首先會針對 struct 傳回 struct 的函式,有 和 的正向宣告。 編譯器假設 struct 使用 C++ 呼叫慣例。 接下來是 struct 定義,預設會使用 C 呼叫慣例。 因為編譯器在完成讀取整個 struct 之前,才知道 的呼叫慣例,所以 在 的傳回型 get_c2 別中,的 呼叫慣例 structstruct 也會假設為 C++。

struct後面接著另一個傳回 的 struct 函式宣告。 此時,編譯器會知道 struct 的呼叫慣例是 C++。 同樣地,傳回 struct 的函式指標會在定義之後 struct 定義。 編譯器現在知道 struct 會使用 C++ 呼叫慣例。

若要解決因呼叫慣例不相容而導致的 C2440 錯誤,請宣告在 UDT 定義之後傳回 UDT 的函式。

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

將零指派給內部指標

如果您將零指派給內部指標,也可能會發生 C2440:

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

使用者定義轉換

C2440 也可能因為使用者定義轉換的使用不正確而發生。 例如,當轉換運算子定義為 explicit 時,編譯器無法在隱含轉換中使用。 如需使用者定義轉換的詳細資訊,請參閱 使用者定義轉換 (C++/CLI) 。 此範例會產生 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 創造

如果您嘗試在類型為 Array 的 C++/CLI 中建立陣列的實例,也可能會發生 C2440。 如需詳細資訊,請參閱陣列。 下一個範例會產生 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));
}

屬性

C2440 也可能因為屬性功能中的變更而發生。 下列範例會產生 C2440。

// c2440f.cpp
// compile with: /LD
[ module(name="PropDemoLib", version=1.0) ];   // C2440
// try the following line instead
// [ module(name="PropDemoLib", version="1.0") ];

元件延伸向下轉換

當您在 下 /clr 編譯原始程式碼時, const_cast Microsoft C++ 編譯器不再允許運算子 向下轉換。

若要解決此 C2440,請使用正確的轉換運算子。 如需詳細資訊,請參閱 轉換運算子

此範例會產生 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
}

符合範本比對變更

C2440 可能會因為 Visual Studio 2015 Update 3 中的編譯器一致性變更而發生。 先前,編譯器在識別作業的 static_cast 範本比對時,錯誤地將特定相異運算式視為相同類型。 現在編譯器會正確區分類型,而依賴先前 static_cast 行為的程式碼會中斷。 若要修正此問題,請變更範本引數以符合範本參數類型,或使用 reinterpret_cast 或 C 樣式轉換。

此範例會產生 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);
}

此錯誤可能會出現在 ATL 程式碼 SINK_ENTRY_INFO 中使用 中所 <atlcom.h> 定義的宏。

Copy-list-initialization

Visual Studio 2017 和更新版本會使用初始化運算式清單正確引發與物件建立相關的編譯器錯誤。 這些錯誤未在 Visual Studio 2015 中攔截,並可能導致當機或未定義的執行時間行為。 在 C++17 複製清單初始化中,編譯器必須考慮明確 construct 或用於多載解析,但如果實際選擇該多載,就必須引發錯誤。

下列範例會在 Visual Studio 2015 中編譯,但不在 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 &'
}

若要更正錯誤,請使用直接初始化︰

// C2440k.cpp
struct A
{
    explicit A(int) {}
    A(double) {}
};

int main()
{
    const A& a2{ 1 };
}

類別 construct 離子中的 cv 限定詞

在 Visual Studio 2015 中,編譯器有時會在透過 construct 或 呼叫產生類別物件時,錯誤地忽略 cv 限定詞。 此瑕疵可能會導致當機或非預期的執行時間行為。 下列範例會在 Visual Studio 2015 中編譯,但在 Visual Studio 2017 和更新版本中引發編譯器錯誤:

struct S
{
    S(int);
    operator int();
};

int i = (const S)0; // error C2440

若要更正錯誤,請將 operator int() 宣告為 const 。