输出地图对象,其中值可以是任何数据类型
output map object where the value can be any data type
正在尝试输出一个地图对象,其中的值可以是任何数据类型。尝试了以下方法:
#include <iostream>
#include <unordered_map>
#include <any>
std::unordered_map<std::string, std::any> example = {
{"first", 'A'},
{"second", 2},
{"third", 'C'}
};
std::ostream &operator<<(std::ostream &os,
const std::any &m) {
for (auto &t : example) {
os << "{" << t.first << ": " << t.second << "}\n";
}
return os;
}
int main()
{std::cout << example;
return 0;
}
但是,获取值的无限循环。
没有打印任意 std::unordered_map<std::string, std::any>
内容的好方法。它可能包含不可打印的内容,并且您已经丢弃了有关内容实际类型的信息。您需要将该信息保存在某个地方。
#include <string>
#include <iostream>
#include <unordered_map>
#include <any>
#include <utility>
template <typename T>
std::ostream & print_any(std::ostream & os, const std::any & any) {
return os << std::any_cast<const std::decay_t<T> &>(any);
}
class any_printable {
using print_t = std::ostream & (*)(std::ostream &, const std::any &);
std::any value;
print_t print;
public:
template <typename T>
any_printable(T&& t) : value(std::forward<T>(t)), print(print_any<T>) {}
friend std::ostream & operator<<(std::ostream & os, const any_printable & ap) {
return ap.print(os, ap.value);
}
};
std::ostream &operator<<(std::ostream &os, const std::unordered_map<std::string, any_printable> &map) {
for (auto & [key, value] : map) {
os << "{" << key << ": " << value << "}\n";
}
return os;
}
int main() {
std::unordered_map<std::string, any_printable> example = {
{"first", 'A'},
{"second", 2},
{"third", 'C'}
};
std::cout << example;
}
另一种方法是将每种类型对应的打印函数注册到散列table中,并使用type_index(any::type)
作为运行时访问相应打印函数的键。
#include <any>
#include <iostream>
#include <unordered_map>
#include <typeindex>
template<class... Ts>
auto gen_any_printer = std::unordered_map{
std::pair{
std::type_index(typeid(Ts)),
+[](std::ostream& os, const std::any& a) -> auto&
{ return os << std::any_cast<Ts const&>(a); }
}...
};
std::ostream& operator<<(std::ostream& os, const std::any& a) {
const static auto any_printer = gen_any_printer<char, int, const char*>;
return any_printer.at(std::type_index(a.type()))(os, a);
}
std::ostream& operator<<(
std::ostream& os, const std::unordered_map<std::string, std::any>& m) {
for (const auto& [key, value] : m)
os << "{" << key << ": " << value << "}\n";
return os;
}
int main() {
std::unordered_map<std::string, std::any> example = {
{"first", 'A'}, {"second", 2}, {"third", "hai"}
};
std::cout << example;
}
正在尝试输出一个地图对象,其中的值可以是任何数据类型。尝试了以下方法:
#include <iostream>
#include <unordered_map>
#include <any>
std::unordered_map<std::string, std::any> example = {
{"first", 'A'},
{"second", 2},
{"third", 'C'}
};
std::ostream &operator<<(std::ostream &os,
const std::any &m) {
for (auto &t : example) {
os << "{" << t.first << ": " << t.second << "}\n";
}
return os;
}
int main()
{std::cout << example;
return 0;
}
但是,获取值的无限循环。
没有打印任意 std::unordered_map<std::string, std::any>
内容的好方法。它可能包含不可打印的内容,并且您已经丢弃了有关内容实际类型的信息。您需要将该信息保存在某个地方。
#include <string>
#include <iostream>
#include <unordered_map>
#include <any>
#include <utility>
template <typename T>
std::ostream & print_any(std::ostream & os, const std::any & any) {
return os << std::any_cast<const std::decay_t<T> &>(any);
}
class any_printable {
using print_t = std::ostream & (*)(std::ostream &, const std::any &);
std::any value;
print_t print;
public:
template <typename T>
any_printable(T&& t) : value(std::forward<T>(t)), print(print_any<T>) {}
friend std::ostream & operator<<(std::ostream & os, const any_printable & ap) {
return ap.print(os, ap.value);
}
};
std::ostream &operator<<(std::ostream &os, const std::unordered_map<std::string, any_printable> &map) {
for (auto & [key, value] : map) {
os << "{" << key << ": " << value << "}\n";
}
return os;
}
int main() {
std::unordered_map<std::string, any_printable> example = {
{"first", 'A'},
{"second", 2},
{"third", 'C'}
};
std::cout << example;
}
另一种方法是将每种类型对应的打印函数注册到散列table中,并使用type_index(any::type)
作为运行时访问相应打印函数的键。
#include <any>
#include <iostream>
#include <unordered_map>
#include <typeindex>
template<class... Ts>
auto gen_any_printer = std::unordered_map{
std::pair{
std::type_index(typeid(Ts)),
+[](std::ostream& os, const std::any& a) -> auto&
{ return os << std::any_cast<Ts const&>(a); }
}...
};
std::ostream& operator<<(std::ostream& os, const std::any& a) {
const static auto any_printer = gen_any_printer<char, int, const char*>;
return any_printer.at(std::type_index(a.type()))(os, a);
}
std::ostream& operator<<(
std::ostream& os, const std::unordered_map<std::string, std::any>& m) {
for (const auto& [key, value] : m)
os << "{" << key << ": " << value << "}\n";
return os;
}
int main() {
std::unordered_map<std::string, std::any> example = {
{"first", 'A'}, {"second", 2}, {"third", "hai"}
};
std::cout << example;
}