gpt4 book ai didi

c++ - 在 boost::spirit::karma 中使用 boost::fusion::map

转载 作者:太空狗 更新时间:2023-10-29 21:25:48 25 4
gpt4 key购买 nike

我正在使用 boost spirit 将一些文本文件解析为数据结构,现在我开始从该数据结构生成文本(使用 spirit karma)。

数据结构的一个尝试是 boost::fusion::map(如对 this问题)。但是,尽管我可以使用 boost::spirit::qi::parse() 并轻松获取其中的数据,但当我尝试使用 karma 从中生成文本时,我失败了。

下面是我的尝试(尤其是“map_data”类型)。在阅读和尝试其他融合类型之后,我发现了 boost::fusion::vector 和 BOOST_FUSION_DEFINE_ASSOC_STRUCT。我成功地用它们生成了输出,但它们似乎并不理想:在 vector 中你不能使用名称访问成员(它就像一个元组)——而在另一个解决方案中,我认为我不需要两种方式(成员名称和 key 类型)访问成员。

#include <iostream>
#include <string>
#include <boost/spirit/include/karma.hpp>
#include <boost/fusion/include/map.hpp>
#include <boost/fusion/include/make_map.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/as_vector.hpp>
#include <boost/fusion/include/transform.hpp>

struct sb_key;
struct id_key;

using boost::fusion::pair;

typedef boost::fusion::map
< pair<sb_key, int>
, pair<id_key, unsigned long>
> map_data;

typedef boost::fusion::vector < int, unsigned long > vector_data;

#include <boost/fusion/include/define_assoc_struct.hpp>
BOOST_FUSION_DEFINE_ASSOC_STRUCT(
(), assocstruct_data,
(int, a, sb_key)
(unsigned long, b, id_key))

namespace karma = boost::spirit::karma;

template <typename X>
std::string to_string ( const X& data )
{
std::string generated;
std::back_insert_iterator<std::string> sink(generated);
karma::generate_delimited ( sink, karma::int_ << karma::ulong_, karma::space, data );
return generated;
}

int main()
{
map_data d1(boost::fusion::make_map<sb_key, id_key>(234, 35314988526ul));
vector_data d2(boost::fusion::make_vector(234, 35314988526ul));
assocstruct_data d3(234,35314988526ul);

std::cout << "map_data as_vector: " << boost::fusion::as_vector(d1) << std::endl;
//std::cout << "map_data to_string: " << to_string(d1) << std::endl; //*FAIL No 1*
std::cout << "at_key (sb_key): " << boost::fusion::at_key<sb_key>(d1) << boost::fusion::at_c<0>(d1) << std::endl << std::endl;

std::cout << "vector_data: " << d2 << std::endl;
std::cout << "vector_data to_string: " << to_string(d2) << std::endl << std::endl;

std::cout << "assoc_struct as_vector: " << boost::fusion::as_vector(d3) << std::endl;
std::cout << "assoc_struct to_string: " << to_string(d3) << std::endl;
std::cout << "at_key (sb_key): " << boost::fusion::at_key<sb_key>(d3) << d3.a << boost::fusion::at_c<0>(d3) << std::endl;

return 0;
}

包括注释行会产生大量编译错误页面,其中特别是如下内容:参数 1 没有从“boost::fusion::pair”到“double”的已知转换参数 1 没有从“boost::fusion::pair”到“float”的已知转换

可能是 to_string 需要 map_data 的值,而不是对?虽然我不擅长模板,但我尝试通过以下方式使用变换从 map 中获取 vector

template <typename P>
struct take_second
{
typename P::second_type operator() (P p)
{
return p.second;
}
};
// ... inside main()
pair <char, int> ff(32);
std::cout << "take_second (expect 32): "
<< take_second<pair<char,int>>()(ff) << std::endl;
std::cout << "transform map_data and to_string: "
<< to_string(boost::fusion::transform(d1, take_second<>())); //*FAIL No 2*

但我不知道在实例化 take_second 时我应该给出什么类型,无论如何我认为必须有一种更简单的方法来获取(迭代) map 的值(有吗?)

如果您回答了这个问题,请同时就使用 ASSOC_STRUCT 还是 map 更好发表您的意见。

最佳答案

我想我注意到了你的问题 on the [spirit-general] list更早。

那里有 14 次浏览 - 我做了一些相当深入的调查。遗憾的是,据我所知,我认为 Spirit 不支持相关的融合结构。

事实上,在 MSM 和 Phoenix 之外,boost 中没有我看到使用 fusion::map 的地方。

您是否有机会改用 std::map/std::pair?这是一个小小的概念证明:

#include <boost/spirit/include/karma.hpp>
#include <boost/fusion/adapted.hpp>

int main()
{
const auto data = std::map<std::string, double> {
{ "pi", 3.1415925 },
{ "e", 2.718281828 },
{ "Answer", 42 } };

namespace karma = boost::spirit::karma;
std::cout << karma::format((karma::string << " = " << karma::double_) % karma::eol, data)
<< std::endl;
}

输出:

Answer = 42.0
e = 2.718
pi = 3.142

关于c++ - 在 boost::spirit::karma 中使用 boost::fusion::map,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13388824/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com