Reputation: 99
I need to initialize vectors and check whether the initialization has been successful many times, so I decided to create a function for that. The problem is that I haven't been able to find a way to tackle this problem without losing a significant amount of efficiency. This has been my attempt so far:
#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;
}
}
}
Notice that I create a new vector and then call the copy constructor, so the cost is similar to initializing two vectors instead of one. Is there an efficient alternative to this?
Upvotes: 0
Views: 561
Reputation: 227518
You cannot initialize something after it has been constructed. However, the simplest "solution" to your "problem" is to construct the vector in place instead of using an "init" function with an "output parameter".
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;
}
}
If you really need an "init" function for your vector, then return by value and use it to initialize something at the caller side.
std::vector<double> init(int n, double x) {
return std::vector<double>(n, x);
}
Both versions leave you with less things to think about. For example, you don't have to instantiate and empty vector first, then check the return value of a function (which you can easily neglect to do) and you don't have to document what happens if a non-empty vector gets passed, or read the documentation if you're the user of the function.
Upvotes: 2
Reputation: 17483
Notice that I create a new vector and then call the copy constructor, so the cost is similar to initializing two vectors instead of one.
I do not think so.
You create an empty std::vector<double> v
, which is a relatively cheap operation, and then assign it a new value inside init()
.
However, in init()
a temporary std::vector<double>(n, x)
is assigned to v
, so the move assignment operator, not the copy constructor, will be called and no unnecessary copying is performed.
Upvotes: 2