[英]Conditionally initialize std::vector from pointer
I am interfacing with some C++ code that has a method providing a pointer and object size (some proprietary library that I can't change).我正在与一些 C++ 代码交互,该代码具有提供指针和 object 大小的方法(一些我无法更改的专有库)。 The interface looks something like this:
界面看起来像这样:
float *arrayPtr();
int arraySize();
I have a class that needs to copy this to a vector (in order to extend its lifetime).我有一个 class 需要将其复制到向量中(以延长其寿命)。 In the scenario where this pointer is not a nullptr, the constructor is fairly simple (I need to copy the data to extend its lifetime):
在此指针不是 nullptr 的情况下,构造函数相当简单(我需要复制数据以延长其生命周期):
struct A {
std::vector<float> vec;
A(float *ptr, int size) : vec( ptr, std::next(ptr, size) ) {}
}
I am, however, a little unsure of how best to handle the initialization when ptr
is a nullptr
.但是,我有点不确定当
ptr
是nullptr
时如何最好地处理初始化。 I could default initialize, and then move everything to the constructor body, but that feels quite inefficient:我可以默认初始化,然后将所有内容移至构造函数主体,但这感觉效率很低:
A(float *ptr, int size) {
if (ptr) {
vec = std::vector<float>( ptr, std::next(ptr, size));
}
}
Are there any other alternatives?还有其他选择吗?
When ptr
is a nullptr
, I would like the vector to just be default initialized to an empty vector.当
ptr
是nullptr
时,我希望将向量默认初始化为空向量。
EDIT:编辑:
It just occurred to me that I should probably be doing this:我突然想到我可能应该这样做:
A(float *ptr, int size) : vec( ptr ? std::vector<float>(ptr, std::next(ptr, size)) : std::vector<float>() ) {}
But perhaps there is a better form??但也许有更好的形式?
This is not necessarily "better" (actually I think your original code is fine, since there is not really any cost to default initialization of a vector), but when you need to perform some logic for an initializer you can use a helper function:这不一定“更好”(实际上我认为您的原始代码很好,因为向量的默认初始化实际上并没有任何成本),但是当您需要为初始化程序执行一些逻辑时,您可以使用帮助程序 function:
struct A {
std::vector<float> vec;
A(float *ptr, int size) : vec( make_A_vector(ptr, size) ) {}
private:
static std::vector<float> make_A_vector(float const *begin, int size)
{
if ( size < 0 || (size > 0 && !begin) )
throw std::runtime_error("invalid array length for A");
if ( size == 0 )
return {};
return std::vector<float>(begin, begin + size);
}
};
Another common design is to keep your class simple and have construction logic entirely in a free function:另一个常见的设计是让您的 class 保持简单,并在免费的 function 中完全具有构造逻辑:
struct A
{
std::vector<float> vec;
};
inline A make_A(float const *ptr, int size)
{
// sanity check omitted for brevity
if ( size == 0 )
return A{};
return A{ std::vector<float>(ptr, ptr + size) };
}
It's an experience-based judgement call as to what would be overkill and what would be aesthetic:)这是一个基于经验的判断,关于什么是矫枉过正,什么是审美:)
Researching what std::next
and the ctor of std::vector
is doing.研究
std::next
和std::vector
的 ctor 正在做什么。 your first try works just fine.你的第一次尝试效果很好。 ONLY and ONLY if your
size
is reliably 0
, when your pointer is a nullptr
.仅当您的
size
可靠地为0
时,当您的指针为nullptr
时。
it - Iterator to base position.
it - 基于 position 的迭代器。 ForwardIterator shall be at least a forward iterator.
ForwardIterator 应至少是一个前向迭代器。
n - Number of element positions offset (1 by default).
n - 元素位置偏移的数量(默认为 1)。 This shall only be negative for random-access and bidirectional iterators.
这仅对随机访问和双向迭代器是负面的。 difference_type is the numerical type that represents distances between iterators of the ForwardIterator type.
difference_type 是表示 ForwardIterator 类型的迭代器之间距离的数值类型。
If you are assured, your given size is 0
, when you get a nullptr
, std::next
returns the same position as your pointer points to.如果您放心,您的给定大小为
0
,当您获得nullptr
时, std::next
返回与指针指向的相同 position 。
You use this ctor:你使用这个ctor:
Constructs the container with the contents of the range [first, last).
使用范围 [first, last) 的内容构造容器。
If your first
and last
are the same, you get an empty std::vector
.如果你的
first
和last
相同,你会得到一个空的std::vector
。 So the nullptr
is never a problem.所以
nullptr
从来都不是问题。
Regardless this findings.不管这个发现。 you should ALWAYS check for
nullptr
's.你应该总是检查
nullptr
的。 For the sake of defensive programming - ALL INPUT IS EVIL!为了防御性编程 - 所有输入都是邪恶的!
You mentioned, the library you get is known for being error prone.您提到过,您获得的库以容易出错而闻名。 Please save yourself much troubles and check every parameter you get out of it of integrity.
请省去很多麻烦,并检查您从中获得的每个参数的完整性。
One comment on your worries that your implementation would perform any worse then an other.一条评论是关于您担心您的实施会比其他实施更差的评论。 Check those implementations in an
loop
with thousands or millions of iterations.在具有数千或数百万次迭代的
loop
中检查这些实现。 Then you can make an prediction if it effects you.然后,如果它影响到你,你就可以做出预测。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.