Parsing in between of brackets
Design

Your main issue is design. Without looking at the rest of your code to understand how it works this is a bit of a guess. But it feels like you have a design issue with your larger algorithm. There are much better ways to solve this without scanning way ahead in the input stream.

As pointed out by @JerryCoffin above in the comments shunting yard or recursive descent are things you should look into. Personally I think the shunting yard algorithm would give you the most benefit at this point.

Review of Code

Iterators are supposed to be very simple object that carry little state. So passing them by value should not be an issue. Also is there a need to limit this to string::iterator?

string get_between_brackets(string::iterator&amp; tail_, const string::iterator&amp; end_)


I would have done:
    string get_between_brackets(string::iterator&amp; tail_, const string::iterator&amp; end_)

template&lt;typename I&gt;
std::string get_between_brackets(I tail_, I end_)


That's a great comment.

    brackets_content.reserve(248); //cannot be longer than that


But i don't see that being enforced anywhere.

This switch is broken:

            switch(chr)
            {
                case '(': ++br_cnt; break;
                case ')': --br_cnt; break;
            }


Any character that does not match ')' or '(' leads to undefined behavior. You should must have a default option.

You throw if there is not enough charaters to hold two braces.

else throw std::invalid_argument("brackets tail is not long enough");


But your code works perfectly well if there are no braces in the code. Also I would expect it to throw if the braces were not balanced.

Also rather than building the result slowly character by character as you parse it. It would be simpler (and more effecient) to just remember the beignning and end and return a sub string.

    return std::string(firstBrace, lastBracePlusOne);