Поделиться через


Ошибка компилятора C2397

Преобразование из "type_1" в "type_2" требует сужения преобразования

Неявное сужение преобразования было найдено при использовании универсальной инициализации.

Язык C позволяет неявно сужать преобразования в назначениях и инициализации, и C++ следует примеру, несмотря на то, что неожиданное сужение является причиной многих ошибок кода. Чтобы сделать код более безопасным, стандарт C++ требует диагностического сообщения, когда сужающее преобразование происходит в списке инициализации. В Visual C++диагностика — ошибка компилятора C2397 при использовании синтаксиса универсальной инициализации, поддерживаемого начиная с Visual Studio 2015. Компилятор создает предупреждение компилятора (уровень 1) C4838 при использовании синтаксиса инициализации списка или статистической инициализации, поддерживаемого Visual Studio 2013.

Сужающее преобразование может быть в порядке, если вы знаете возможный диапазон преобразованных значений, которые могут соответствовать целевому объекту. В этом случае вы знаете больше, чем компилятор. Если вы делаете сужающее преобразование намеренно, сделайте свои намерения явными с помощью статического приведения. В противном случае это сообщение об ошибке почти всегда указывает на наличие ошибки в коде. Это можно исправить, убедившись, что объекты, инициализируемые, имеют достаточно большие типы для обработки входных данных.

Следующий пример приводит к возникновению ошибки C2397:

// C2397.cpp
// compile with: /c
struct S {
   int m1;
   double m2, m3;
};

void func(double d1) {
   char c1 { 127 };   // OK
   char c2 { 513 };   // C2397
   
   S arr[2]{};
   arr[0] = { d1, 2.0, 3.0 };   // C2397
   arr[1] = { static_cast<int>(d1), 2.0, 3.0 };   // OK
}