
Eric Niebler skrev:
Thorsten Ottosen wrote:
Hi Eric,
My semantic actions might look like
+(name[push_back(ref(causeNames),as<std::string>(_) )]);
My first question here is whether ref() is really necessary?
The issue is one of lifetime management. Consider:
sregex make_regex( int &i, int j ) { sregex rx = (some >> regex)[ ref(i) += j ]; // TODO return rx; }
What happens to 'j'? If we follow your suggestion, 'j' should be held by reference. Then when make_regex returns, the resulting regex object is left holding a dangling reference to an int. That's why anything not wrapped in ref() is held *by value* by the regex. So that's why ref() is needed in your case.
Right.
Have a look at xpressive::local<> and xpressive::reference<> as ways of decorating an object so that xpressive knows how to store it in an action.
Ok, but let me make the question more specific: why would you ever pass a container by value to push_back()?
I also have another question: is it really necessary to write the as<std::string>(_) part of the semantic action?
Can this type not be deduced from the template argument to push_back()? In my case it would simply be Container::value_type.
If so, we would end up with the really slick looking
+(name[push_back(causeNames)]);
No, push_back takes two arguments, and I don't want to get into the game of making xpressive semantic actions too clever by a half by trying to guess what you mean, or "know" the semantics of push_back, etc.. However, in a semantic action, _ stands in for a sub_match object, which happens to have an implicit conversion to std::string. So this should work:
// Untested. local<std::vector<std::string> > causeNames; sregex rx = +(name[ push_back(causeNames, _) ]);
Ok, that is neat, but I still don't get what you mean when you say or "know" the semantics of push_back, etc.. Don't we know the semantics? I thought the whole point was to call the member function called push_back on a container that supports that operation. -Thorsten