unordered_map 和 std::any 值不能 any_cast 字符串
unordered_map with std::any values cannot any_cast string
我是 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;
}
您插入的所有值都是 int
,但您试图将底部的单个值转换为 char const*
;它不是任何类型的指针,看起来 any_cast
的类型足够安全,可以拒绝该尝试(这是一件好事,因为取消引用指向内存地址 8745
的指针可能会导致段错误)。您正在检查早期代码中的类型,并可能在那里选择了正确的转换。
我是 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;
}
您插入的所有值都是 int
,但您试图将底部的单个值转换为 char const*
;它不是任何类型的指针,看起来 any_cast
的类型足够安全,可以拒绝该尝试(这是一件好事,因为取消引用指向内存地址 8745
的指针可能会导致段错误)。您正在检查早期代码中的类型,并可能在那里选择了正确的转换。