如何将boost :: any打印到流中?

Fra*_*ank 16 c++ printing boost boost-any

我有一个Map std::map<std::string, boost::any>,来自boost::program_options包.现在我想打印该地图的内容:

for(po::variables_map::const_iterator it = vm.begin(); it != vm.end(); ++it) {
  std::cerr << it->first << ": " << it->second << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,这是不可能的,因为boost::any没有operator<<定义.

打印该地图最简单的方法是什么?

我可以为任何自动尝试将每个输出运算符定义为anyint,然后是double,然后是字符串等,每次忽略错误并尝试强制转换直到转换成功并且我可以打印为指定类型.

但是在Boost中应该有一个更简单的方法吗?我需要像反向的东西lexical_cast......

hka*_*ser 29

你可以boost::spirit::hold_any改用.它在这里定义:

#include <boost/spirit/home/support/detail/hold_any.hpp>
Run Code Online (Sandbox Code Playgroud)

并完全兼容boost::any.如果相对于该类有两个区别boost::any:

  • 它利用小对象优化习惯和其他一些优化技巧,使得spirit::hold_any更小更快boost::any
  • 它定义了流操作符(operator<<()operator>>()),允许spirit::hold_any无缝输入和输出.

唯一的限制是你不能输入一个空spirit::hold_any,但它需要持有一个(可能是默认构造的)从输入中预期的类型的实例.

  • 它只是Spirit的一部分,主要是因为我既没有时间也没有能量让它取代`boost :: any`. (2认同)

mil*_*bug 5

如果您可以更改boost::any为其他类型,则可以使用Boost.TypeErasure.如果你想创建一个类似的类型any,但只支持在编译时支持这些特定操作的类型,那么这只适合你.

#include <boost/type_erasure/operators.hpp>
#include <boost/type_erasure/any.hpp>
#include <boost/mpl/vector.hpp>
#include <random>
#include <iostream>

namespace te = boost::type_erasure;

typedef te::any<boost::mpl::vector<
    te::copy_constructible<>,
    te::destructible<>,
    te::ostreamable<>
>> streamable_any;

int main()
{
    streamable_any i(42);
    streamable_any d(23.5);
    std::mt19937 mt;
    streamable_any r(mt);
    std::cout << i << "\n" << d << "\n" << r << "\n";
}
Run Code Online (Sandbox Code Playgroud)

Live On Coliru


Aki*_*oss 0

我认为你必须涵盖你必须打印的对象的每种可能情况......或者使用 boost::variant。

编辑:抱歉,我想我应该写为什么。

我认为这是因为,查看任何源代码,它似乎依赖于您在插入和获取数据时提供类型的事实。当您插入时,编译器会自动检测数据,因此您不必指定它。但是当你获取数据时,你应该使用any_cast,因为你不确定你得到的数据类型。

如果它以不同的方式工作并且数据类型是确定的,我认为就不需要 any_cast :)

相反,变体具有一组有限的可能数据类型,并且此信息在某种程度上已注册,使您能够以通用方式迭代变体容器。

如果您需要这种操作 - 迭代一组通用值 - 我认为您应该使用变体。