What's the proper way to set a std::vector to another std::vector?

I'm trying to figure out the optimal way to do this assignment.

Right now I'm just doing a simple assignment, but was wondering if using std::swap() would be better or if maybe there is just a better way to write this code so that I can replace my initial list with what I build up during the validation pass.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
std::vector<int> tets_to_use;

//... add entries to tets_to_use

//Validate
while (true) {
	std::vector<int> tets_validated;
	
	for (int tet_idx: tets_to_use) {
		if (is_valid(tet_idx))
			tets_validated.push_back(tet_idx);
	}
	
	if (tets_validated.size() == tets_to_use.size())
		break;
	
	//Something was not valid - try again with reduced list
	tets_to_use = tets_validated;
}

Last edited on
TBH, this looks like a std::list would be a better fit.

You can remove elements in place from a list, and all you need to keep track of is whether you've removed anything in a traversal of the list.

Also consider remove_if() on tets_to_use. You're not trying to set a std::vector to another std::vector - you're removing elements that don't satisfy a criteria.

https://en.cppreference.com/w/cpp/algorithm/remove.html
https://en.cppreference.com/w/cpp/algorithm/ranges/remove.html

As test code to remove odd numbers from a vector, consider:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <algorithm>
#include <vector>

int main() {
	const auto odd { [](auto n) {return n % 2; } };

	const auto disp { [](auto v) {
		std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
		std::cout << '\n';
	} };

	std::vector nos = { 1, 2, 3, 4, 5, 6 };

	disp(nos);

	nos.erase(std::remove_if(nos.begin(), nos.end(), odd), nos.end());

	disp(nos);
}

Last edited on
If you want to assign one vector to another, and if the "source" vector is not needed anymore after this assignment, then I think a move-assignment would be the best (most efficient) choice here:

vec1 = std::move(vec2);

Normal assignment leaves the "source" vector unchanged, so the data actually needs to be duplicated into the "destination" vector. That is inefficient, if you don't need the "source" vector anymore after the assignment (as is the case here). Meanwhile, move-assignment allows the "destination" vector to steal the data from the "source" vector, leaving the "source" vector in a valid but unspecified state.

(However, I'm not sure whether compiler optimizations would already turn the regular assignment into a move-assignment automatically for you in this situation 🤷)

Furthermore, I think an std::swap() pretty much does the same thing as a move-assignment, only that it happens in both directions at the same time: Vector a steals the data from vector b, while vector b steals the data from vector a. That is probably okay, performance-wise, but I think an explicit move-assignment is more clear, because it more clearly expresses what your intention is.
Last edited on
Registered users can post here. Sign in or register to post.