【发布时间】:2011-11-09 13:40:19
【问题描述】:
我使用karma 来生成大型结构的表示,但是在生成过程中会复制这些结构。我不认为他们需要这样做,所以想知道如何避免它。
下面的快速示例打印“复制!”,因为目标结构被复制到rule::generate:
namespace karma = spirit::karma;
namespace phoenix = boost::phoenix;
struct foo
{
foo() { }
foo( foo const &other ) { std::cout << "Copy!"; }
int f() const { return 42; }
};
std::string output;
typedef std::back_insert_iterator< std::string > iterator;
karma::rule< iterator, foo() > foo_rule =
karma::int_[ karma::_1 = phoenix::bind( &foo::f, karma::_val ) ];
foo my_foo;
iterator it( output );
karma::generate( it, foo_rule, my_foo );
我可以通过引用声明foo_rule的属性来停止复制:
karma::rule< iterator, foo &() > foo_rule
但这不适用于向量[显然foos 因此是可复制的,但在向量构造时复制可能很便宜,但在生成时复制成本高:-)]
下面的示例打印“复制!”生成期间五次(即在向量 ctor 期间忽略副本);如果foo_rule 的属性不是引用,则为 10 次:
std::vector<foo> my_vec_foo(5);
karma::rule< iterator, std::vector<foo>() > vec_foo_rule = *foo_rule;
karma::generate(it, vec_foo_rule, my_vec_foo);
在 VC 2008 上使用 Boost 1.47 无法编译同时引用这两个规则。也就是说,使用:
karma::rule< iterator, foo &() > foo_rule /* = ... */;
karma::rule< iterator, std::vector<foo> &() > vec_foo_rule /* = ... */;
我用Attribute = std::vector<foo> 和Exposed=std::vector<foo> & 实例化了extract_from_container。在 extract_from.hpp 的第 131 行,它尝试形成 Exposed const & 并且在创建引用引用时编译器失败。
我觉得我错过了一些东西,所以任何指针都将不胜感激!
【问题讨论】:
-
+1 表示极好的最小问题。也许,你可以让它更加复制/粘贴(现在对 Spirit 没有深入了解的人不太可能让它运行)。我测试了我的答案,帖子包含了一个完整的最小样本。干杯
标签: c++ boost-spirit boost-spirit-karma