Заполнение вектора пар

Я хочу заполнить вектор 8 парами. Каждая пара представляет собой ходы по координатам x и y, которые может сделать рыцарь в шахматной игре. На данный момент я делаю это так:

vector<pair<int,int>> moves[8];

pair<int,int> aPair;
aPair.first = -2;
aPair.second = -1;
moves[0].push_back(aPair);
aPair.first = -2;
aPair.second = 1;
moves[1].push_back(aPair);
aPair.first = -1;
aPair.second = -2;
moves[2].push_back(aPair);
aPair.first = -1;
aPair.second = 2;
moves[3].push_back(aPair);
aPair.first = 1;
aPair.second = -2;
moves[4].push_back(aPair);
aPair.first = 1;
aPair.second = 2;
moves[5].push_back(aPair);
aPair.first = 2;
aPair.second = -1;
moves[6].push_back(aPair);
aPair.first = 2;
aPair.second = 1;
moves[7].push_back(aPair); 

Я делаю это, чтобы узнать о библиотеке Std. Это кажется безнадежно неэффективным способом решения этой проблемы.

У кого-то есть более элегантное решение?

Ответы

Ответ 1

Циклы на помощь:

for(int k = 0; k < 2; k++)
    for(int i = -1; i < 2; i += 2)
        for(int j = -1; j < 2; j+= 2)
            result.push_back(make_pair(i * (k+1), j * (((k + 1) % 2) + 1)));

Выход: http://ideone.com/2B0F9b

Ответ 2

Если у вас есть С++ 11 (иначе вы не можете написать >>), вы можете использовать следующее:

vector<pair<int,int>> moves = {
  {-2, -1},
  {-2,  1},
  {-1, -2},
  {-1,  2},
  { 1, -2},
  { 1,  2},
  { 2, -1},
  { 2,  1}
};

Ответ 3

В С++ 98/03:

moves.push_back(std::make_pair(-2, -1));

В С++ 11:

moves.emplace_back(-2, -1);

Альтернативно в С++ 11:

std::vector<std::pair<int, int>> moves = { { -2, -1}, ... };

Ответ 4

Если у вас нет С++ 11, вы можете использовать make_pair, предварительно выделить пространство для вектора без инициализации элементов, используя резерв, и затем используйте push_back без выполнения новых распределений.

Например:

vector<pair<int,int> > moves;
moves.reserve(8);
moves.push_back(make_pair(-2, -1));
    // and so on

Даже если у вас есть С++ 11, этот метод полезен, если вам нужно вычислить элементы "на лету", а не жестко кодировать их.

Ответ 5

Попробуйте следующее:

vector<pair<int,int>> moves{{-2, -1}, {2, 1}, {-1, -2}, {-1, 2},
                            {1, -2},  {1, 2}, {2, -1},  {2, 1}};

Список инициаторов вместе с Uniform Initialization дает большую мощность в С++ 11.

Ответ 6

Вот еще один способ сделать то же самое.

template <class VectorClass>
class CreateVector
{
public:
    typedef typename VectorClass::value_type value_type;
    CreateVector(const value_type& value)
    {
        mVector.push_back(value);
    }

    CreateVector& operator()(const value_type& value)
    {
        mVector.push_back(value);
        return *this;
    }

    inline operator VectorClass() const
    {
        return mVector;
    }
private:
    VectorClass mVector;
};

Использование:

vector<pair<int,int>> moves = CreateVector<vector<pair<int,int> > >
(make_pair(1,2))
(make_pair(2,3))
(make_pair(3,4))
(make_pair(4,5));

EDIT: если вы не используете С++ 11, это будет один из способов. В противном случае я бы предложил пойти по пути @ipc.

Ответ 7

Если вы используете С++ 11, вы можете рассмотреть std:: array вместо std::vector. Как и обычный массив, массив std имеет фиксированное количество элементов и имеет более концептуальный смысл, если вы заранее знаете, сколько данных вы используете.

Ответ 8

Надеемся, что более читаемая версия с циклами:

vector<pair<int, int>> result;
for(int moveX=1; moveX<=2; moveX++)
{
    for(int signX=-1; signX<=1; signX+=2)
    {
        for(int signY=-1; signY<=1; signY+=2)
        {
            result.push_back(make_pair(moveX*signX, (3-moveX)*signY));
        }
    }
}

Полная программа создает следующий вектор:

{-1, -2},
{-1, 2},
{1, -2},
{1, 2},
{-2, -1},
{-2, 1},
{2, -1},
{2, 1},