Сужение преобразования от 'int' до 'double' и инициализация массива

Следующие

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 такое "большой" тип?

0 ответов

Другие вопросы по тегам