我想在不知道值的情况下流式传输 std::any
。
我知道有std::any.type()
,但我不确定如何在std::any_cast<type>(thatAny)
中使用它。
这是我尝试的代码:
std::cout << std::any_cast<a.type()>(a) << std::endl;
你需要将如何流式传输的内容存储在某处。
有几种不同的方法。如果你可以集中列举或注册所有可以流式传输的类型,你可以创建从typeid到流式编码的映射,然后使用该映射来流式传输你特定的std::any
。
std::unordered_map< std::type_index, void(*)(std::any const&, std::ostream&)> streamers;
template<class T>
void add_streamer() {
streamers[ typeid(T) ] = [](std::any const& a, std::ostream& os ) {
os << std::any_cast<T>(a);
};
}
template<class...Ts>
void add_streamers() {
( void(add_streamer<T>()), ... );
}
void stream( std::ostream& os, std::any const& a ) {
streamers[ a.type() ]( a, os ); // maybe check errors!
}
另一个方案是增强您的any
实例。
struct streamable_any : std::any {
void(*streamer)(std::ostream&, streamable_any const&) = nullptr;
friend std::ostream& operator<<( std::ostream& os, streamable_any const& a ) {
a.streamer( os, a );
return os;
}
template<class T,
std::enable_if_t<!std::is_same<std::decay_t<T>, streamable_any>{}, bool> = true
>
streamable_any( T&& t ):
std::any( std::forward<T>(t) ),
streamer([](std::ostream& os, streamable_any const& self ) {
os << std::any_cast<std::decay_t<T>>(self);
} )
{}
};
现在,一个streamable_any
只存储可流式传输的类型,并将如何进行流式传输的函数指针与实例一起存储。
更安全的streamable_any
不会公开继承自std::any
,因为通过转换到基类修改std::any
将会破坏流式传输。这只是由于any_cast
等操作带来的痛苦。
实时示例。
wstreamable_any
稍微有些不同。 - Yakk - Adam Nevraumontstreamable_any(streamable_any&)
;我希望它能调用streamable_any(streamable_any const&)
,以及一些类似的情况。 - undefined这并非直接可行。
然而,如果您有一个T
,不要直接存储它,而是存储{T, [](T const& t) { using std::to_string; return to_string(t); }}
。也就是说,对于每个T
,都存储一个序列化该特定T
的lambda表达式。
另外,您可以保留std::any
,但将其包装在自定义类型中,并在std::any
旁边存储适当的[](std::any const& a) { return to_string(std::any_cast<T>(a));}
。例如,如果插入了一个int
,则还会创建并存储一个[](std::any const& a) { return to_string(std::any_cast<int>(a));}
。
type()
是运行时值,而模板参数必须是编译时常量。 - François Andrieuxstd::any
都是错误的。 - StoryTeller - Unslander Monicastd::any
而不是std::variant<...>
? - MSalters