c++ – Efficient way to encode moves and container choice for chess moves for an engine

I am working on my chess engine in C++ and I went for bitboards to represent the board. It is basically a 64-bit number for which I use the bitset library. I feel the most crucial part in performance comes through the move generation. Earlier I encoded moves as std::string‘s in a std::vector which would perform moves on a 2-D array. A move has to include at the most basic, A start location, and an end location. That means for my purpose, two numbers would be enough. However, it shall also include two more attributes which are, castling rights(if any) en-passant squares.

One choice is to use a struct to represent two coordinates and the additional two attributes. And then create an array of those moves.

Another choice is to use a 16-bit number to represent a move. For example:
6-bits for the first number, 6-bits for the second. And the remaining for the additional values.
And then store them in an array/vector/any container.

Even a std::vector<int> can work.

The main purpose is to be able to iterate through the container efficiently as it will happen multiple times.

What is the best way to encode the move?