通过适当的转换,用 double 的 std::array 元素填充 int 的 std::array 的最简单方法是什么?

What is the easiest way to fill std::array of int with elements of std::array of double with proper casting?

我想在使用 std::array<int, 4> 的函数中使用 std::array<double, 4>?

那么,最简单/最短(两者)实现该目标的方法是什么。

例如

#include <array>
#include <iostream>

void printInts(std::array<int, 4> someInts) {
    for(int someInt : someInts) {    
        std::cout << someInt << std::endl;
    }
}

std::array<double, 4> someDoubles{1.1, 2.2, 3.3, 4.4};

int main() {
    printInts(someDoubles); // of course it doesn't work
    return 0;
}

非常感谢您的帮助 ;)

P.S

1
2
3
4

当然是预期输出。

如果您不能更改函数 PrintInts,那么您可以只创建数组的 int 版本,然后用它调用函数:

std::array<int, 4> ints;
std::copy(std::begin(someDoubles), std::end(someDoubles), std::begin(ints));
printInts(ints);

请注意,从 double 转换为 int 可能会因为缩小转换而失去精度。如果转换后的 double 值不能用 int.

表示,这甚至可能导致 UB

这是 demo

cigien 建议使用 std::array<double, N> 中的值填充 std::array<int, N> 的一个很好的简短方法。 但是,如果您想要一个 returns std::array<int, N> 的专用命名函数,那么它将类似于

#include <array>
#include <iostream>

void printInts(const std::array<int, 4> &someInts) {
    for (int someInt : someInts) {
        std::cout << someInt << std::endl;
    }
}

template <size_t N>
std::array<int, N> castToInts(const std::array<double, N> &someDoubles) {
    std::array<int, N> result;
    for (int i = 0; i < N; i++) {
        result[i] = static_cast<int>(someDoubles[i]);
    }
    return result;
}

std::array<double, 4> someDoubles{ 1.1, 2.2, 3.3, 4.4 };

int main() {
    printInts(castToInts(someDoubles)); // now we can call like this
    return 0;
}

如果您想要更简单,可以删除 template <size_t N> 并硬编码 4 而不是 N.

顺便说一句,我稍微改变了你的printInts,查找有关通过引用传递对象参数

最简单,因为只需要做一些小改动就可以printInts做你想做的事:

void printAsInts(std::array<double, 4> someDoubles) {
    for (double someDouble : someDoubles) {
        std::cout << static_cast<int>(someDouble) << '\n';
    }
}

最短(而且可以说是简单)因为它依赖于标准库提供的设施,所以你甚至不需要写一个循环:

#include <algorithm>
#include <array>
#include <iterator>
#include <iostream>

std::array<double, 4> someDoubles{1.1, 2.2, 3.3, 4.4};

int main() {
    std::transform(someDoubles.begin(), someDoubles.end(),
                   std::ostream_iterator<int>(std::cout, "\n"),
                   [](double x) { return static_cast<int>(x); });
    return 0;
}

上面的答案也比其他一些答案更有效,因为它不必创建第二个数组。只有四个元素,第二个数组的成本不是很大,但如果数组的大小很大,那么您可能不想实例化一个临时数组。它也更有效,因为 std::endl 需要比需要更频繁地刷新输出缓冲区。

更一般。不可否认,这不是最简单或最短的编写方式,但是,一旦编写完成,它就是最容易使用的,并且它提供了很大的灵活性,因为您可以在不触及打印代码的情况下更改容器的类型。

#include <algorithm>
#include <array>
#include <iterator>
#include <iostream>
#include <utility>

template<typename T, typename Iter>
void printAs(Iter begin, Iter end) {
    std::transform(begin, end, std::ostream_iterator<T>(std::cout, "\n"),
                   [](const auto &x) { return static_cast<T>(x); });
}

template<typename T, typename Container>
void printAs(const Container &container) {
    printAs<T>(std::begin(container), std::end(container));
}

std::array<double, 4> someDoubles{1.1, 2.2, 3.3, 4.4};

int main() {
    printAs<int>(someDoubles);
    return 0;
}