исключение bad_any_cast при возврате строки из шаблонной функции - PullRequest
1 голос
/ 23 апреля 2020

Я создаю парсер файла конфигурации со значениями, хранящимися в unordered_map. Значения конфигурации представляют собой смесь строк, целых чисел, чисел с плавающей точкой и значений типа bools, поэтому я использую std :: any для их хранения в неупорядоченной карте следующим образом:

static unordered_map<string, any> CONFIG_VALUES =
{
    {"title",           "The window title"},
    {"xRes",            1024},
    //...
};

У меня есть шаблон c Функция получения, позволяющая получить значения конфигурации следующим образом:

template<typename T>
T GetValue(const string& valueName) const
{
    auto result = CONFIG_VALUES.find(valueName);
    if (result != CONFIG_VALUES.end())
    {
        return any_cast<T>(result->second);
    }
    else
    {
        throw std::runtime_error("Invalid config key");
    }
}

Мой код компилируется, и я могу успешно извлечь int следующим образом:

int myXres = MyConfig->GetValue<int>("xRes");

Но, если Я пытаюсь получить строку:

string myTitle = MyConfig->GetValue<string>("title");

Я получаю cra sh:

Unhandled exception at 0x00007FF99463A799 in program.exe: Microsoft C++ exception: std::bad_any_cast at memory location 0x000000DCD76FDCE8. occurred

В локальных отладчиках Visual Studio я вижу, что строка std :: any типа строки is

type    0x00007ff6950f2328 {program.exe!char const * `RTTI Type Descriptor'} {_Data={_UndecoratedName=0x0000000000000000 <NULL> ...} }  

Я подозреваю, что здесь может быть проблема "char const *" (потому что мы передаем "string" в качестве параметра шаблона), но я не уверен, как это исправить. .. (или, может быть, это красная сельдь).

Есть идеи?

1 Ответ

1 голос
/ 23 апреля 2020

Вы правы относительно значения char const*. Вам нужно будет сохранить его как std::string на карте, например:

static unordered_map<string, any> CONFIG_VALUES =
{
    {"title",           std::string("The window title")},
    {"xRes",            1024},
    //...
};

В качестве альтернативы, вы можете сделать any_cast для правильного типа, например:

string myTitle = GetValue<char const*>("title");

Вот рабочая демоверсия .

...