通过适当的转换,用 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;
}
我想在使用 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
.
这是 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;
}