我正在使用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
但这对矢量不起作用[显然foo
是可复制的,但在矢量构造中复制可能很便宜,但在生成时复制起来很昂贵: - )]
以下示例打印'复制!'在生成期间五次(即,在矢量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 /* = ... */;
我通过extract_from_container
和Attribute = std::vector<foo>
实例化Exposed=std::vector<foo> &
。在extract_from.hpp的第131行,它尝试形成Exposed const &
,并且在创建引用引用时编译器失败。
我觉得我错过了什么,所以任何指针都会非常感激!
答案 0 :(得分:3)
我确定你已经尝试过,但我会说它。你试过如下:
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);
更新我刚刚使用下面的代码段(带有Boost 1.47.0的g ++ 4.6)对其进行了测试。它证实了上述工作原理。但是,存在混淆的余地,因为std::vector<foo> my_vec_foo(5)
也将显示5个副本。请参阅代码和输出中的BIG LETTER警告:
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace karma = boost::spirit::karma;
namespace phoenix = boost::phoenix;
struct foo
{
foo() { }
foo( foo const &other ) { std::cerr << "Copy!\n"; }
int f() const { return 42; }
};
int main()
{
std::string output;
typedef std::back_insert_iterator< std::string > iterator;
iterator it( output );
karma::rule< iterator, foo&() > foo_rule =
karma::int_[ karma::_1 = phoenix::bind( &foo::f, karma::_val ) ];
foo my_foo;
karma::generate( it, foo_rule, my_foo );
std::vector<foo> my_vec_foo(5);
std::cerr << "\nSTART WATCHING NOW" << std::endl;
karma::rule< iterator, std::vector<foo>&() > vec_foo_rule = *foo_rule;
karma::generate(it, vec_foo_rule, my_vec_foo);
}
输出:
Copy!
Copy!
Copy!
Copy!
Copy!
START WATCHING NOW