map to structs всегда возвращает последнюю структуру в векторе <struct> - PullRequest
0 голосов
/ 04 февраля 2020

У меня есть вектор или структура. Я создаю структуры на месте, используя emplace_back. Затем я сопоставляю указатель на каждую структуру с картой указателей.

Однако позже, когда я пытаюсь вызвать структуры, карта всегда получает последнюю структуру.

#include <map>
#include <vector>
#include <iostream>

using namespace std;

// -------------------------------
//      Asset Pair
// -------------------------------
    struct asset_pair {

        // Member Variables
            int ID_1;
            int ID_2;
            int pair_ID;

        // Constructor
            asset_pair(const int id_1, const int id_2) : ID_1(id_1) , ID_2(id_2)
            {
                pair_ID = ( ((id_1 & 0xFFFF) << 16) | ((id_2 & 0xFFFF) << 0));
            };
    };

std::map<int, asset_pair*> pair_id_map;

// -------------------------------------
//      Pair Exists
// -------------------------------------
    bool pair_exists(const int id_1, const int id_2)
    {
        int pair_id = (((id_1 & 0xFFFF) << 16) | ((id_2 & 0xFFFF) << 0));

        return pair_id_map.find(pair_id) != pair_id_map.end();
    }



/******************************************************/
/*                  Main                              */
/******************************************************/

int main() {


    // Asset Pair Vector
        std::vector<asset_pair> Asset_Pairs;

        Asset_Pairs.reserve(10);
        int pair_counter = 0;

    // Asset ID's
        int asset_ids[5];

        for (int i=0; i<6; i++)
            asset_ids[i] = i + 1;

    // Create Pairs - in place
        for (auto id_1 : asset_ids)
        {
            for (auto id_2 : asset_ids)
            {
                if (id_1 == id_2)
                    continue;

                // Create Pair
                    Asset_Pairs.emplace_back(asset_pair(id_1, id_2));
                    auto new_pair = *(Asset_Pairs.begin() + pair_counter);
                    pair_counter ++;

                // Pair ID map
                    asset_pair *p_pair = &new_pair;
                    pair_id_map[new_pair.pair_ID] = p_pair;

                // Sanity Check
                    cout << "Creating Pair :: " << new_pair.pair_ID << " || " << new_pair.ID_1 << ":" << new_pair.ID_2 << "\n";
            }

            cout << "--------------\n";
        }

    // Access Pairs
        for (auto id_1 : asset_ids)
        {
            for (auto id_2 : asset_ids)
            {
                if (id_1 == id_2)
                    continue;

                if (pair_exists(id_1, id_2))
                {
                    // Get Pair
                        int pair_id = ( ((id_1 & 0xFFFF) << 16) | ((id_2 & 0xFFFF) << 0));
                        auto new_pair = pair_id_map[pair_id];

                    // Print
                        cout << "Access Pair :: " << new_pair->pair_ID << " -- ";
                        cout << new_pair->ID_1 << "|" << new_pair->ID_2 << "\n";
                }

            }
        }


}

Вывод

// ---------------------
//   :: Create Pairs ::
// ---------------------
// Creating Pair :: 65538 || 1:2
// Creating Pair :: 65539 || 1:3
// Creating Pair :: 65540 || 1:4
//   ~ ~ ~
// Creating Pair :: 327683 || 5:3
// Creating Pair :: 327684 || 5:4

// ---------------------
//   :: Access Pairs ::
// ---------------------
// Access Pair :: 327684 -- 5|4
// Access Pair :: 327684 -- 5|4
//  ~ ~ ~
// Access Pair :: 327684 -- 5|4
  • Инициализировать вектор
    • создать структуры на месте
  • добавить пару на карту: [ID, * pair]
  • пара доступа: [ID, * пара]

1 Ответ

2 голосов
/ 04 февраля 2020
auto new_pair = *(Asset_Pairs.begin() + pair_counter);
asset_pair *p_pair = &new_pair;
pair_id_map[new_pair.pair_ID] = p_pair;

приведет к сохранению указателя на локальную переменную new_pair на вашей карте. Вам нужно изменить new_pair на указатель или ссылку:

auto &new_pair = *(Asset_Pairs.begin() + pair_counter);

Или, поскольку Asset_Pairs - это вектор, который вы можете просто использовать

auto &new_pair = Asset_Pairs[pair_counter];

или

auto &new_pair = Asset_Pairs.back();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...