我试图从std::span<uint8_t,N>
创建std::array<uint8_t,N>
,但我找不到一种方法来这样做,没有memcpy
,std::copy
,或std::ranges::copy
,这不能保护我免受错误的目标数组大小的规范。
#include <algorithm>
#include <array>
#include <iostream>
#include <span>
int main(int argc, char **argv) {
constexpr size_t N = 10;
std::array<uint8_t, N> original;
std::span span(original); // of type std::span<uint8,N>
std::array copy1(span); // does not work
std::array<uint8_t, N> copy2(span); // does not work
std::array<uint8_t, N> copy3(begin(span), end(span)); // does not work
// ugly stuff that works, but does not protect me if I specify wrong array size
constexpr size_t M{N - 1}; //oops, leads to array overflow
std::array<uint8_t, M> copy4;
std::copy(begin(span), end(span), copy4.begin());
std::ranges::copy(span, copy4.begin());
return 0;
}
字符串
在现代C++中,实现这一点的惯用方法是什么?
3条答案
按热度按时间rpppsulh1#
但是如果没有
memcpy
、std::copy
或std::ranges::copy
,我就找不到这样做的方法,因为它们不能防止错误指定目标数组大小。如果一个
span
有一个 static 扩展区,它的size()
可以实现为一个常量表达式,它可以在当前的主流编译器上工作:字符串
或者,您可以通过其静态成员常量
extent
(如std::array<uint8_t, span.extent>
)获取size值,这是可以保证工作的。wfsdck302#
你可以把它 Package 在一个函数中:
字符串
注意:我避免使用
std::copy
,因为它需要有T
的默认构造函数(用于初始数组)。xlpyo6sf3#
为了扩展@Jarod42的答案,我们可以做一些改进:
字符串
如果要进一步减小部件大小,可以使用以下条件:
型
如果您担心
std::ranges::copy
在初始化过程中会产生开销,那么可以使用std::is_trivially_default_constructible_v<T>
,也可以与std::ranges::uninitialized_copy
一起使用,这样可以减轻这种情况。