ovanes
ovanes

Reputation: 5673

lambda function capture and modify own reference

Sometimes there is a need to execute a particular function once and than switch to another implementation.

For example, I am really annoyed by the stream output iterator which prints delimiter after the item being printed in conjunction with the copy algorithm:

> 1,2,3,4,
         ^---- this is what happens in that case

The question isn't about nicely printing items, but more about properly concatenating them.

For example Python produces a correct result using string.join function:

','.join((1,2,3,4))
> 1,2,3,4

I also want to avoid if/else statement, because we only need once to make the switch after the first execution. So what I came up with, is:

std::function<char const*()> get_delim;

get_delim = [&get_delim]()
{
  get_delim = [](){ return ","; };
  return "";
};

for(auto b : some_byte_range)
  std::cout << get_delim() << b;

Note: b is just a byte in my case, that's why I did not use auto const&.

Now the questions:

Upvotes: 0

Views: 261

Answers (1)

Barry
Barry

Reputation: 302817

In this case, all you need is:

auto get_delim = [c=char(0)]() mutable {
    char cur = c;
    c = ',';
    return cur;
};

or even:

auto get_delim = [c=char(0)]() mutable { return std::exchange(c, ','); }

Or use "" and "," if you prefer, should be easy to see how to adjust this to suit your needs.


As far as library goes, there is a std::experimental::ostream_joiner.

Upvotes: 4

Related Questions