Следующие
int i = 0;
double d{i};
выдает ошибку (в clang) или предупреждение (в gcc) narrowing conversion from 'int' to 'double'
, Мне показалось удивительным, что это действительно сужается, по крайней мере, пока я не увидел сужение конверсии от неподписанного до двойного.
мой актуальная проблема происходит от класса, который содержит массив и предоставляет конструктор для определения элементов массива самым простым способом (пересылка):
template<typename T, size_t N>
struct A
{
T a[N];
template<typename... E>
A(E&&... e) : a{std::forward<E>(e)...} { }
};
В этом случае имеем следующее (живой пример):
int i = 0;
A<double, 2> x(i, 2); // ERROR for both 'i' and '2'
double y[2]{i, 2}; // ERROR for 'i' only
где ERROR
относится к сужению конверсии, как обсуждалось выше. Я подозреваю, что все эти ошибки сводятся к тому, что упоминалось в начале (double d{i};
). Это так? Иначе что происходит?
Во всяком случае, мне бы очень хотелось
A<double, 2> x(i, 2);
работать так же, как
double x(i);
работает. К сожалению, я могу только инициализировать массив, используя список инициализаторов, который также проверяет сужающие преобразования. Я знаю один обходной путь, чтобы сделать явное приведение в конструкторе:
template<typename... E>
A(E&&... e) : a{static_cast <T>(e)...} { }
или (спасибо Марк)
template<typename... E>
A(E&&... e) : a{static_cast <T>(std::forward<E>(e))...} { }
но это ли «правильный» путь? И является ли это наиболее эффективным, когда E
такое «большой» тип?
Задача ещё не решена.
Других решений пока нет …