Я использую карму для генерации представлений больших структур, но структуры копируются во время генерации.Я не думаю, они должны быть, поэтому мне было интересно, как этого избежать.
В приведенном ниже быстром примере напечатано "Копировать!", Поскольку целевая структура копируется в 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);10 раз, если атрибут foo_rule
не является ссылкой:
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 в VC 2008. То есть с:
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> &
.В строке 131 файла extract_from.hpp он пытается сформировать Exposed const &
, и при создании ссылки на ссылку происходит сбой компилятора.
Мне кажется, что я что-то упустил, поэтому любые указатели будут очень благодарны!