无法计算 std::any 容器中的项目
Cant cout item in container with std::any
这个脚本
#include <iostream>
#include <unordered_map>
#include <any>
using namespace std;
int main() {
unordered_map<int, any> test;
test[5] = "Hey!";
cout << test[5];
return 0;
}
为什么不起作用?
candidate function not viable: no known conversion from 'std::__ndk1::unordered_map<int, std::__ndk1::any, std::__ndk1::hash<int>, std::__ndk1::equal_to<int>, std::__ndk1::allocator<std::__ndk1::pair<const int, std::__ndk1::any> > >::mapped_type' (aka 'std::__ndk1::any') to 'const void *' for 1st argument; take the address of the argument with &
basic_ostream& operator<<(const void* __p);
对不起,如果这听起来有点愚蠢
要解决此错误,您可以使用 std::any_cast
,它使 type-safe 可以访问包含的对象,如下所示:
std::cout << std::any_cast<const char*>(test[5]);
或者
test[5] = std::string("Hey!");
std::cout << std::any_cast<std::string>(test[5]);
这是因为没有为 std::ostream
和 std::any
的 <<
运算符定义重载。
<<
是为字符串文字、std::string
、数字和其他一些特定对象定义的。 std::any
是其中的 none。
仅仅因为它碰巧实际包含一个字符串并不能使它成为 std::string
或其他任何东西。仅仅因为你打开车门,进去坐下,或者把你的狗或一堆杂货放进车里,并不会把你的车变成人、狗或一堆蔬菜。它仍然是一辆汽车,只是里面有东西。
因此没有为此定义 <<
运算符。这就是您的 C++ 编译器告诉您的内容:它需要为 std::ostream
和 std::any
定义的 <<
运算符,但没有。
只需在 test[5]
中添加一个 any_cast
。这种转换的主要原因是告诉编译器要为 test[5]
调用 <<
的哪个重载函数,<<
没有为 std::any
定义任何函数.因此,我们告诉编译器调用 <<
.
的 const char *
或 std::string
重载函数
始终确保 test[n]
的分配 sizeof
必须与 sizeof
type-cast 匹配。
例如:
sizeof(std::string) = 32 bytes
sizeof(const char *) = 8 bytes
这就是为什么我们首先需要使用 std::string("Hey!");
分配 test[5]
而不是 "Hey!"
.
但是,sizeof(int *)
等于 sizeof(char *)
,如果这样做,可能会导致 3 个问题:
- 段错误
- 未定义的行为
- 异常:
std::bad_any_cast
修复
std::cout << std::any_cast<const char *>(test[5]);
或std::string
test[5] = std::string("Hey!");
std::cout << std::any_cast<std::string>(test[5]);
这个脚本
#include <iostream>
#include <unordered_map>
#include <any>
using namespace std;
int main() {
unordered_map<int, any> test;
test[5] = "Hey!";
cout << test[5];
return 0;
}
为什么不起作用?
candidate function not viable: no known conversion from 'std::__ndk1::unordered_map<int, std::__ndk1::any, std::__ndk1::hash<int>, std::__ndk1::equal_to<int>, std::__ndk1::allocator<std::__ndk1::pair<const int, std::__ndk1::any> > >::mapped_type' (aka 'std::__ndk1::any') to 'const void *' for 1st argument; take the address of the argument with &
basic_ostream& operator<<(const void* __p);
对不起,如果这听起来有点愚蠢
要解决此错误,您可以使用 std::any_cast
,它使 type-safe 可以访问包含的对象,如下所示:
std::cout << std::any_cast<const char*>(test[5]);
或者
test[5] = std::string("Hey!");
std::cout << std::any_cast<std::string>(test[5]);
这是因为没有为 std::ostream
和 std::any
的 <<
运算符定义重载。
<<
是为字符串文字、std::string
、数字和其他一些特定对象定义的。 std::any
是其中的 none。
仅仅因为它碰巧实际包含一个字符串并不能使它成为 std::string
或其他任何东西。仅仅因为你打开车门,进去坐下,或者把你的狗或一堆杂货放进车里,并不会把你的车变成人、狗或一堆蔬菜。它仍然是一辆汽车,只是里面有东西。
因此没有为此定义 <<
运算符。这就是您的 C++ 编译器告诉您的内容:它需要为 std::ostream
和 std::any
定义的 <<
运算符,但没有。
只需在 test[5]
中添加一个 any_cast
。这种转换的主要原因是告诉编译器要为 test[5]
调用 <<
的哪个重载函数,<<
没有为 std::any
定义任何函数.因此,我们告诉编译器调用 <<
.
const char *
或 std::string
重载函数
始终确保 test[n]
的分配 sizeof
必须与 sizeof
type-cast 匹配。
例如:
sizeof(std::string) = 32 bytes
sizeof(const char *) = 8 bytes
这就是为什么我们首先需要使用 std::string("Hey!");
分配 test[5]
而不是 "Hey!"
.
但是,sizeof(int *)
等于 sizeof(char *)
,如果这样做,可能会导致 3 个问题:
- 段错误
- 未定义的行为
- 异常:
std::bad_any_cast
修复
std::cout << std::any_cast<const char *>(test[5]);
或std::string
test[5] = std::string("Hey!");
std::cout << std::any_cast<std::string>(test[5]);