我需要初始化向量并检查初始化是否已成功多次,所以我决定为此创建一个函数。问题是我还没有找到解决这个问题的方法而不会失去很大的效率。到目前为止,这是我的尝试:
#include <iostream>
#include <vector>
bool init(std::vector<double>& v, int n, double x) {
try {
v = std::vector<double>(n, x);
}
catch (std::bad_alloc& e) {
std::cerr << "Error: " << e.what() << std::endl;
return false;
}
return true;
}
int main() {
int n = -1;
std::vector<double> v;
if (not init(v, n, 1)) {
std::cerr << "Vector failed to initialize" << std::endl;
}
else {
for (int i = 0; i < n; ++i) {
std::cout << v[i] << std::endl;
}
}
}
请注意,我创建了一个新的向量,然后调用了复制构造函数,因此成本类似于初始化两个向量而不是一个向量。有没有一种有效的替代方案?
答案 0 :(得分:2)
请注意,我创建了一个新的向量,然后调用了复制构造函数,因此成本类似于初始化两个向量而不是一个向量。
我不这么认为。
您创建一个空的std::vector<double> v
,这是一个相对便宜的操作,然后在init()
内为其分配一个新值。
但是,在init()
中,临时std::vector<double>(n, x)
被分配给v
,因此将调用移动赋值运算符,而不是复制构造函数,并且不会执行不必要的复制。
答案 1 :(得分:2)
构建后,您无法初始化。但是,对“问题”最简单的“解决方案”是在适当的位置构造向量,而不是使用带有“输出参数”的“init”函数。
int main() {
int n = -1;
try
{
std::vector<double> v(n, 1);
for (int i = 0; i < n; ++i) {
std::cout << v[i] << std::endl;
}
}
catch(const std::bad_alloc&)
{
std::cerr << "Vector failed to initialize" << std::endl;
}
}
如果您确实需要向量的“init”函数,则按值返回并使用它在调用者端初始化某些内容。
std::vector<double> init(int n, double x) {
return std::vector<double>(n, x);
}
这两个版本都会让您少考虑一些事情。例如,您不必首先实例化和清空向量,然后检查函数的返回值(您可以轻易忽略它),并且您不必记录如果传递非空向量会发生什么,如果您是该功能的用户,请阅读文档。