正如 reima 已经指出的那样,如果您只想引用现有序列,则强制转换myvector.data()
为int*
(假设sizeof(mypoint) == 2 * sizeof(int)
保持)就足够了。但是,如果您明确想要一个展平序列的副本,您最好创建一个像这样的小型实用程序函数:
template <typename T, typename U>
std::vector<T> flatten(std::vector<U> const& other) {
static_assert(std::is_trivially_copyable<U>::value,
"source type must be trivially copyable!");
static_assert(std::is_trivially_copy_constructible<T>::value,
"destination type must be trivially copy constructible!");
static_assert((sizeof(U) / sizeof(T)) * sizeof(T) == sizeof(U),
"sizeof(U) must be a multiple of sizeof(T)!");
return std::vector<T>(reinterpret_cast<T const*>(other.data()),
reinterpret_cast<T const*>(std::next(other.data(), other.size())));
}
template <typename U>
std::vector<typename U::value_type> flatten(std::vector<U> const& other) {
return flatten<typename U::value_type>(other);
}
减少你的代码
auto newvector = flatten<int>(myvector);
或者 - 如果你为你配备mypoint
struct
(符合 STL 的)value_type
成员类型 - 甚至
auto newvector = flatten(myvector);
请注意,这个实用函数只不过是一个经过调整的构造函数,它使用固有的不安全reinterpret_cast
将mypoint
指针转换为int
指针。为了摆脱伴随使用的安全警告reinterpret_cast
,该flatten
函数使用了一些static_assert
降落伞。因此,最好将所有这些隐藏在一个单独的函数中。尽管如此,它还是使用了许多 C++11 特性auto
,例如移动构造、static_assert
类型特征,std::next
并且vector::data()
几乎将您的调用站点代码剥离到最低限度。
此外,这是尽可能高效的,因为 range 构造函数vector
只会执行内存分配和调用uninitialized_copy
,这可能会归结为memcpy
对普通可复制类型的调用。