Как преобразовать std :: array <double, 100> в std :: array <float, 100>? (избегая очевидной стандартной реализации) - PullRequest
0 голосов
/ 12 июня 2019

Предположим, у меня есть std::array двойных чисел, и я хотел бы, чтобы он был преобразован в числа с плавающей точкой:

std::array<double, 100> d_array{1,2,3};
std::array<float, 100> f_array; <--convert it from d_array;

При использовании std::vector это чрезвычайно просто:

std::vector<float> f_array(d_array.begin(), d_array.end());

Iзнаете, std::array является агрегированным типом, поэтому мне кажется, что мне нужно сделать несколько ручных переходов на месте, чтобы скопировать его в массив, или есть удобный способ сделать это?

Я считаю std::copy шаблон также, например ::

std::array<float, 100> f_array;
std::copy(d_array.begin(), d_array.end(), f_array.begin());

Это не проще, чем векторная версия и не может быть :

const std::array<float, 100> f_array;

Таким образом, разрушая иначе const-правильный код.

Ответы [ 3 ]

3 голосов
/ 12 июня 2019

Вы можете написать простую функцию преобразования. Мне не известны какие-либо стандартные или улучшающие функции, но их довольно просто реализовать:

template <typename T, typename U, size_t N, size_t... Is>
std::array<T, N> array_cast(const std::array<U, N>& arr, std::index_sequence<Is...>) {
    return { static_cast<T>(arr[Is])... };
}

template <typename T, typename U, size_t N>
std::array<T, N> array_cast(const std::array<U, N>& arr) {
    return array_cast<T>(arr, std::make_index_sequence<N>());
}

Чтобы использовать, просто позвоните array_cast<float>(d_array)

Пример

3 голосов
/ 12 июня 2019

Я сомневаюсь, что есть однострочное решение, но в двух строках:

std::array<float, 100> f_array;
std::copy(d_array.begin(), d_array.end(), f_array.begin());

См. std::copy.

2 голосов
/ 12 июня 2019

Хотя Майлз Буднек ответ решает проблему OP, он может завершиться ошибкой, если массив слишком большой (обратите внимание, что вы просите компилятор сгенерировать и выполнить функцию с Nпараметры).См., Например, этот пример .

Альтернативой может быть использование простого цикла for, который, начиная с C ++ 14, разрешен внутри constexpr функций.

template< class R, class T, size_t N>
constexpr std::array<R, N> array_copy(std::array<T, N> const &src)
{
    std::array<R, N> tmp {};
    for (size_t i{}; i < N; ++i)
        tmp[i] = static_cast<R>(src[i]);
    return tmp;
}

Live ЗДЕСЬ .

...