Предупреждение о принудительном сужении преобразования, но избегайте сужения предупреждения int->двойного преобразованияC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Предупреждение о принудительном сужении преобразования, но избегайте сужения предупреждения int->двойного преобразования

Сообщение Anonymous »

Подобно описанной здесь проблеме, мне нужно создать класс шаблона, который должен предоставить конструктор преобразования любого типа. Конструктор конверсий должен определять сужающиеся конверсии.

Код: Выделить всё

template
struct X
{
T v_;

// Add conversion constructor here
};
... итак, следующий код компилируется без ошибок и предупреждений:

Код: Выделить всё

// g++ -Wall -Werror -Werror=narrowing ./2.cpp

#include 
#include 

template
void test(X) {}

int main()
{
test(1);
test("1");
}
Проблема в том, что я хочу, чтобы конструктор преобразования молчал при преобразовании int -> double, когда входные данные представляют собой постоянное выражение, как описано в стандарте C++:

[dcl.init.list]
{7} Сужающее преобразование — это неявное преобразование
7.3) из целочисленного типа или типа перечисления с незаданной областью в тип тип с плавающей запятой, кроме, где источником является постоянное выражение, а фактическое значение после преобразования будет соответствовать целевому типу и будет создавать исходное значение при преобразовании обратно в исходный тип, или

В случае, если я определяю конструктор преобразования следующим образом:

Код: Выделить всё

X(T v) : v_(v) {}
... отлично работает, если T == double, но не работает, если T == string_view и тип входного параметра — char const*

Код: Выделить всё

./2.cpp:26:32: error: could not convert ‘(const char*)"1"’ from ‘const char*’ to ‘X’
26 |         test("1");
В случае, если я определяю этот конструктор следующим образом:

Код: Выделить всё

template
X(Other const& v) : v_{v} {}
...он прекрасно работает с std::string_view, но выдает предупреждение о сужении преобразования, если T == double и тип входного аргумента — int:

Код: Выделить всё

./2.cpp:17:23: error: narrowing conversion of ‘(int)v’ from ‘int’ to ‘double’ [-Werror=narrowing]
17 |   X(Other const& v) : v_{v} {}
|                       ^~~~~
Ни один из следующих ответов не отвечает на мой вопрос:
  • Вывод шаблонов и неявные конструкторы: есть ли способ заставить вывод шаблонов работать с неявным преобразованием?
  • Как использовать функцию шаблона для неявного преобразования
  • Сужение преобразования от char к double
Один из вариантов, который я вижу, — это объявить два конструктора:
  • Один для случая, когда T является типом с плавающей запятой
  • Другой для остальных случаев.
... но, похоже, это излишество.
Другой вариант — объявить один конструктор и включить его, Enable_if_t, если OtherT можно преобразовать в T без потери данных. Мне просто нужно использовать такую ​​функцию:

Код: Выделить всё

template>
X(Other const& v) : v_(static_cast(v)) {}
В этом случае вместо предупреждения будет сообщено о серьезной ошибке, что в моем случае нормально.
Есть ли другие варианты?

Подробнее здесь: https://stackoverflow.com/questions/798 ... version-wa
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»