Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ cout映射boost::any_C++_Boost_Cout - Fatal编程技术网

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';
    }
}