【问题标题】:bad_any_cast exception when returning string from templated function从模板化函数返回字符串时出现 bad_any_cast 异常
【发布时间】:2020-04-23 15:53:23
【问题描述】:

我正在创建一个配置文件解析器,其值存储在 unordered_map 中。配置值是字符串、整数、浮点数和布尔值的混合,所以我使用 std::any 将它们存储在无序映射中,如下所示:

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

我有一个通用的 getter 函数,可以像这样检索配置值:

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");

我遇到了崩溃:

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

在 Visual Studio 调试器本地我看到 std::any 类型的字符串是

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

我怀疑“char const *”可能是这里的问题(因为我们将“string”作为模板参数传递),但我不知道如何解决它......(或者,也许这个是红鲱鱼)。

有什么想法吗?

【问题讨论】:

  • 我不确定std::any"The window title" 存储为哪种类型,但我不明白为什么它更倾向于将其存储为std::string。可能是const char *。尝试在地图初始化程序中使用 std::string("The window title")
  • std::any 是一种生硬的工具,通常不值得它所要求的价格。考虑使用 std::variant 仅包含您的配置值可能具有的类型。
  • 谢谢 - 原来,它被存储为一个 char const*,因为我现在意识到,这就是我定义的 :)

标签: c++ string templates exception any


【解决方案1】:

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");

这是一个有效的demo

【讨论】:

  • 也可以使用 std::string 字面量:"The window title"s
猜你喜欢
  • 2011-10-21
  • 2013-08-16
  • 2013-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-31
  • 1970-01-01
相关资源
最近更新 更多