根据指针条件初始化std::vector
Conditionally initialize std::vector from pointer
我正在与一些C++代码接口,这些代码有一个提供指针和对象大小的方法(一些我无法更改的专有库(。界面看起来像这样:
float *arrayPtr();
int arraySize();
我有一个类需要将其复制到向量中(以便延长其寿命(。在这个指针不是nullptr的场景中,构造函数相当简单(我需要复制数据以延长其寿命(:
struct A {
std::vector<float> vec;
A(float *ptr, int size) : vec( ptr, std::next(ptr, size) ) {}
}
然而,当ptr
是nullptr
时,我有点不确定如何最好地处理初始化。我可以默认初始化,然后将所有内容移动到构造函数主体,但这感觉效率很低:
A(float *ptr, int size) {
if (ptr) {
vec = std::vector<float>( ptr, std::next(ptr, size));
}
}
还有其他选择吗?
当ptr
是nullptr
时,我希望向量默认初始化为空向量。
编辑:
我突然想到我可能应该这么做:
A(float *ptr, int size) : vec( ptr ? std::vector<float>(ptr, std::next(ptr, size)) : std::vector<float>() ) {}
但也许还有更好的形式??
这不一定"更好"(实际上我认为你的原始代码很好,因为向量的默认初始化实际上没有任何成本(,但当你需要为初始化器执行一些逻辑时,你可以使用一个帮助函数:
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);
}
};
另一个常见的设计是保持类的简单性,并将构建逻辑完全放在一个自由函数中:
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) };
}
这是一个基于经验的判断,关于什么是过度杀戮,什么是美学:(
研究std::next
和std::vector
的ctor在做什么。你的第一次尝试效果很好。ONLY和ONLY如果您的size
是可靠的0
,当您的指针是nullptr
时。
std::next(it, n)
it-迭代到基本位置。ForwardIterator应至少为前向迭代器。
n-偏移的元素位置数(默认为1(。这仅对随机访问和双向访问是负面的迭代器。difference_type是表示ForwardIterator类型的迭代器之间的距离。
如果你确信,你的给定大小是0
,当你得到一个nullptr
时,std::next
会返回你的指针指向的相同位置。
std::vector
你使用这个ctor:
构建包含范围[第一个,最后一个(内容的容器。
如果first
和last
相同,则会得到一个空的std::vector
。所以nullptr
从来都不是问题。
不管这些发现如何。您应该始终检查nullptr
的。为了防御编程-所有输入都是邪恶的!
你提到过,你得到的库以容易出错而闻名。请给自己省去很多麻烦,并检查你从中得到的每个参数的完整性。
关于您担心您的实现会比另一个执行得更差的一条评论。在具有数千或数百万次迭代的loop
中检查这些实现。然后,如果它影响到你,你可以做出预测。
- 使用std::vector的OpenCL矩阵乘法
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- std::vector的包装器,使数组的结构看起来像结构的数组
- 编译器如何区分std::vector的构造函数
- 使用 pqxx 将 std::vector 存储在 postgresql 中,并从数据库中检索它
- 在std::vector上存储带有模板的类实例
- 在main()之外初始化std::vector会导致性能下降(多线程)
- 为什么std::vector比数组慢
- std::vector::迭代器是否可以合法地作为指针
- 如何将二进制格式的 C++ 对象的 std::vector 保存到磁盘?
- 为什么std::vector和std::valarray初始化构造函数不同
- ";结果类型必须是可从输入范围的值类型""构造的;创建std::vector时
- 在没有未定义行为的情况下实现类似std::vector的容器
- 如何调整 std::vector of Eigen::MatrixXd 的大小
- 使用 std::vector::reverse_iterator 将 int 序列化为字节向量?
- 如何将AERT_Allocate与 std:vector 一起使用
- 推导 std::vector::back() 的返回类型
- 如何将原始字节附加到 std::vector?
- std::vector 没有重载函数的实例与参数列表匹配
- 如果 KEY 是 std::list 或 std::vector 而不是值,那么 std::map 的默认行为是什么?