将 const float* 转换为 std::array<float, ...>
Convert const float* to std::array<float, ...>
我有一个指向巨大数组的常量浮点*,并希望能够通过 std::array 访问元素。最好的方法是什么?如果可能,无需复制元素。
谢谢!
为了使用std::array
,你需要在编译时知道数组的大小。创建一个空数组并使用 std::copy
将元素复制到数组中。
如果使用您的const float*
的代码在运行时只知道该大小,那么您不能使用std::array
,而必须使用std::vector
。 std::vector
有一个构造函数,您可以将指针传递到范围的开头和结尾以复制到其中。
请注意,在这两种情况下,容器都拥有原始元素的副本。
如果可能,无需复制元素。
不,这是不可能的。C++标准容器旨在拥有其内容,而不仅仅是表示其中的视图。
下面是一个说明差异的示例:
#define SIZE 10 // let's assume some C or legacy code which uses macros
// ...
void f(const float* arr)
{
// size is known at compile time
std::array<float, SIZE> a;
std::copy(arr, arr + SIZE, begin(a));
}
void g(const float* arr, int size)
{
// size is only known at runtime
std::vector<float> v(arr, arr + size);
}
标准库中至少有两个建议的添加功能可以做类似的事情。 一种是std::experimental::to_array<T,N>()
,它制作了整个数据的深层副本。 这在时间和内存方面都是浪费的,但如果您确实想要创建副本,尤其是无法创建然后修改的const
副本,则可能会很有用。
如果您想要的是由任意指针和元素计数表示的数据范围的容器接口,指南支持库提供了一个span
模板。 我建议,如果你同时传递两者,你把它们包装在一个类似于这个的轻量级对象中。
既然你说你可以将接口更改为构造函数,我强烈建议你这样做。 如果要保留采用std::array
的版本,则可以将其委托给采用任意数据范围的版本,例如:
#include <algorithm>
#include <array>
#include <iterator>
#include "span"
MyClass::MyClass( const span<value_type>& s /*, more, params */ )
{
/* In this example, m_storage is some private container and span has a
* container interface.
*/
auto it = std::back_inserter(m_storage);
std::copy_n( s.begin(), s.size(), it );
// ...
}
MyClass::MyClass( std::array<value_type, initializer_size>& a /*, more, params */ )
: MyClass( span<value_type>( a.data(), a.size() ) /*, more, params */ )
{}
std::array 不拥有指针的所有权。您必须复制元素。使用 std::copy。它适用于抽象迭代器,指针也符合这些条件。
const float *source = ...; // C array of at least of size N
std::array<float, N> destination;
std::copy(source, source + N, destination.begin());
顺便说一句:在不复制元素的情况下,任何支持获取指针所有权的容器的元素类型也必须是 const float。或者,如果您确定指针实际上不是真正的常量浮动,则必须使用const_cast<>。请仅在由于外部 API 中的缺陷而绝对不可避免的情况下使用 const_cast<> :)
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 呼叫运营商<<临时
- 如何防止clang格式在流运算符调用之间添加换行符<<
- <<操作员在下面的行中工作
- System.InvalidCastException - SQL to C++ - safe_cast<float>
- 没有从阵列<float>到阵列<int>的可行转换
- 数组下标的类型"float*[float]"无效
- 没有合适的构造函数可以从"float"转换为"_D3DCOLORVALUE"
- 为什么我会收到此错误?无法将 {lb, ub} 从<大括号括起来的初始值设定项列表>转换为 float(**)(float*, int)
- 将 **float array 从 C++ Dll 传递给 python
- 错误:二进制'operator*' 'float'和'float[0]'类型的操作数无效
- float* 已在 Gameobject.obj 中定义
- 如何将 qml 的文本转换为 float 和 int
- 为什么将 1 添加到 numeric_limits<float>::min() 返回 1?
- 有没有比static_cast更优雅的从int到float的演员阵容<float>?
- 编译器给出错误:format 指定类型 'float *',但参数的类型'double' [-Wformat]
- OPENCL 警告:不兼容的指针类型将'float __global[16]'传递给类型为 '__global float4 的参数 *
- 错误:无法将"float*"转换为"float"
- 如何在函数中将字符串和分数存储为(Int 或 float)
- 缩小从double到float的转换