unordered_map со значениями std :: any не может строка any_cast - PullRequest
0 голосов
/ 14 июня 2019

Я новичок в C ++, и я изучал около std::unordered_map и std::any.Я создал демонстрационную демонстрацию ниже, которая генерирует некоторые фиктивные данные, а затем они вставляются в карту.

После этого (в закомментированном коде) я печатаю значения, используя any_cast с успехом.

Однако внизу, как вы можете видеть, я пытаюсь получить определенный ключ с 0 успехами.Я получаю ошибку Bad any_cast, и приведение в точности совпадает с кодом, который я использовал для печати (который в настоящее время закомментирован).

Извините, если это глупая ошибка, но яЯ совсем новый.Заранее спасибо.

#include <iostream>
#include <string>
#include <any>
#include <map>
#include <unordered_map>
#include <time.h>
#include <Windows.h>

std::unordered_map<std::string, std::any> map = {};

int main() {

    unsigned long started = clock();
    const std::string prefix = "key";

    for (int i = 0; i < 1000000; i++) {

        const std::string key = "key" + std::to_string(i);

        map.insert_or_assign(key, i);

    }

    std::cout << "Data inserted after: " << (clock() - started) << "ms" << std::endl;

    system("pause");

    started = clock();

    /*
    for (const auto& item : map) {


        try {

            //std::cout << item.second.type().name() << std::endl;
            if (item.second.type() == typeid(int)) {
                std::cout << std::any_cast<const int>(item.second) << std::endl;
            }
            else if (item.second.type() == typeid(float)) {
                std::cout << std::any_cast<const float>(item.second) << std::endl;
            }
            else if (item.second.type() == typeid(double)) {
                std::cout << std::any_cast<const double>(item.second) << std::endl;
            }
            else if (item.second.type() == typeid(long)) {
                std::cout << std::any_cast<const long>(item.second) << std::endl;
            }
            else if (item.second.type() == typeid(char const *)) {
                std::cout << std::any_cast<char const *>(item.second) << std::endl;
            }
            else if (item.second.type() == typeid(std::string)) {
                std::cout << std::any_cast<const std::string>(item.second) << std::endl;
            }
            else {
                std::cout << item.first << " has an unhandled value type of " << item.second.type().name() << std::endl;
            }

        }
        catch (const std::bad_any_cast& err) {
            std::cerr << err.what() << std::endl;
        }



    }

    std::cout << "Map iterated after: " << (clock() - started) << "ms" << std::endl;

    */

    try {

        auto value = std::any_cast<char const *>(map["key8745"]);

        std::cout << "Key " << value << " retrieved after: " << (clock() - started) << "ms" << std::endl;

    }
    catch (const std::bad_any_cast &err) {
        std::cerr << err.what() << std::endl;
    }

    system("pause");

    return 0;

}

1 Ответ

1 голос
/ 14 июня 2019

Все значения, которые вы вставляете, равны int с, но вы пытаетесь привести единственное значение внизу к char const*; это не указатель любого типа, и похоже, что any_cast достаточно безопасен для того, чтобы отклонить эту попытку приведения (хорошая вещь, поскольку разыменование указателя на адрес памяти 8745 может привести к сбою). Вы проверяете тип в более раннем коде и, по-видимому, выбираете правильное приведение там.

...