C++ cout映射boost::any
我有一个可以嵌套的“字典”C++ cout映射boost::any,c++,boost,cout,C++,Boost,Cout,我有一个可以嵌套的“字典”std::map(或者std::any)。现在,我想显示地图。由于boost::any显然不能很好地处理因此,您可以做一件事来减轻(但不能消除)痛苦,那就是将类型确定逻辑考虑到一个支持函数中,同时对要应用于值的操作使用静态多态性(特别是模板) #include <iostream> #include <boost/any.hpp> #include <string> struct Printer { std::ostream
std::map
(或者std::any
)。现在,我想显示地图。由于boost::any
显然不能很好地处理因此,您可以做一件事来减轻(但不能消除)痛苦,那就是将类型确定逻辑考虑到一个支持函数中,同时对要应用于值的操作使用静态多态性(特别是模板)
#include <iostream>
#include <boost/any.hpp>
#include <string>
struct Printer
{
std::ostream& os_;
template <typename T>
void operator()(const T& t)
{
os_ << t;
}
};
template <typename F>
void f_any(F& f, const boost::any& a)
{
if (auto p = boost::any_cast<std::string>(&a)) f(*p);
if (auto p = boost::any_cast<double>(&a)) f(*p);
if (auto p = boost::any_cast<int>(&a)) f(*p);
// whatever handling for unknown types...
}
int main()
{
boost::any anys[] = { std::string("hi"), 3.14159, 27 };
Printer printer{std::cout};
for (const auto& a : anys)
{
f_any(printer, a);
std::cout << '\n';
}
}
如果您有许多操作,并且希望减少内存使用,那么可以让模板化构造函数创建并存储(抽象基类)指向一个静态类型特定类的指针,该类来自一个抽象接口,您想支持的操作是这样的:这样一来,每个代码只添加一个指针。SujyOn.< /Cult>对象。 < P>因为您已经使用Boost,可以考虑。
它已经有预定义的流式操作符(都是operator()
)
只有嵌入类型必须定义相应的运算符,但在您的使用上下文中,这似乎是完全安全的
尽管在detail
名称空间中,hold_any
非常广泛,几乎是一个随时可用的boost:any
替代品(例如,)
需要最新版本的Boost(旧版本有一个)。然后不要使用Boost::any
。如果要对“可打印”类型进行类型擦除,则需要将打印逻辑粘贴到类型擦除器中。我认为有一个实验性的“Boost.TypeErasure”(可能不在Boost中),它允许您为特定目的合成类型擦除类。您可能只需要长双精度,std::maxiint\t
和std::maxiint\t
就可以覆盖所有内置类型。但正如科雷克所说,如果你想要普通的印刷,你需要把它放在你的打字机橡皮擦里。@MartinBonner:你说的“侥幸逃脱”是什么意思?那代码看起来怎么样?我对boost::any不太熟悉,但是你能问它“你能把封闭的对象转换成一个std::maxuint\t
?如果能,请把它给我吗?”。只要小心一点,就可以用一个大小写覆盖unsigned char、unsigned short、unsigned int、unsigned long、unsigned long和所有其他“unsigned”类型。嗯。不确定-你可以把一个浮点数转换成一个无符号的长整数。@MartinBonner:不,没有这种可能。任何东西都不能“转换”任何东西,因为它不知道它所持有的是什么。你必须告诉它你认为它持有什么!下面是中相应的例子。@KerrekSB:cool-谢谢。我也无意中发现了,这正是我在最后一段中所描述的……是的——所有这些方法都需要对每个特性进行单独的动态调度。使用Boost.TypeErasure,您可以创建一个具有所有所需功能的自定义类型,并且只需要一个动态调度。@KerrekSB:我以前没有看过TypeErasure,您上面的陈述让我有点困惑。如果“feature”的意思是支持前缀递增、流式传输或添加,那么——据我所知——您一次只想做其中一个,通过动态调度来做任何事情都是合理的:每一个都有一个虚拟函数可以正常工作。这就是我最后一段的内容。15年前,我会使用宏来混合不同的操作——现在不使用可变模板是愚蠢的,所以类型擦除是一个可靠的建议。@KerrekSB我不会称之为“对应的例子”。大概是吧。
{
fruit: banana
taste: {
sweet: 1.0
bitter: 0.1
}
}
#include <iostream>
#include <boost/any.hpp>
#include <string>
struct Printer
{
std::ostream& os_;
template <typename T>
void operator()(const T& t)
{
os_ << t;
}
};
template <typename F>
void f_any(F& f, const boost::any& a)
{
if (auto p = boost::any_cast<std::string>(&a)) f(*p);
if (auto p = boost::any_cast<double>(&a)) f(*p);
if (auto p = boost::any_cast<int>(&a)) f(*p);
// whatever handling for unknown types...
}
int main()
{
boost::any anys[] = { std::string("hi"), 3.14159, 27 };
Printer printer{std::cout};
for (const auto& a : anys)
{
f_any(printer, a);
std::cout << '\n';
}
}
#include <iostream>
#include <boost/any.hpp>
#include <string>
#include <functional>
struct Super_Any : boost::any
{
template <typename T>
Super_Any(const T& t)
: boost::any(t),
printer_([](std::ostream& os, const boost::any& a) { os << boost::any_cast<const T&>(a); })
{ }
std::function<void(std::ostream&, const boost::any&)> printer_;
};
int main()
{
Super_Any anys[] = { std::string("hi"), 3.14159, 27 };
for (const auto& a : anys)
{
a.printer_(std::cout, a);
std::cout << '\n';
}
}