4

Given an istream_iterator<int> and multimap<char, int> output.

I want to copy all the values into output's 'a' key. How's the best way to handle that?

I had tried to use:

transform(
    istream_iterator<int>(input),
    istream_iterator<int>(),
    begin(output),
    [](const auto value){
        return make_pair('a', value);
    }
)

But I'm getting the error:

error: assignment of read-only member std::pair<const char, int>::first

I think this means I can't write to begin(output). Is my only option to use for_each?

rocambille
  • 15,398
  • 12
  • 50
  • 68
Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288

1 Answers1

7

You're very close, but you should use std::inserter:

transform(
    istream_iterator<int>(input),
    istream_iterator<int>(), 
    inserter(output, begin(output)),
    [](const auto value){
        return make_pair('a', value);
    }
);

The second parameter is a hint, but for multimap it's going to be ignored. The interface demands that you provide it, though.

rocambille
  • 15,398
  • 12
  • 50
  • 68
krzaq
  • 16,240
  • 4
  • 46
  • 61
  • This is beyond the scope of the original question, but why does `multimap` provide `begin` if I can't use it? Why not just provide `cbegin`? – Jonathan Mee Oct 21 '16 at 15:18
  • 2
    @JonathanMee you can use it, just not in this operation. The actual `value_type` is `std::pair` and you can use `begin(m)` to modify the value. You cannot overwrite the key, because then you'd have to resort the map. If you look at `std::set`, where there's only a const key, you'll notice that it doesn't offer a non-const iterator. – krzaq Oct 21 '16 at 15:22
  • 1
    Ah, so you're saying I'm free to modify the value returned by `multimap::begin` but not the key, which also means that I can't assign. I get it, thanks. So to continue these beyond the scope questions, if `output` already had contents I'd need to be doing `inserter(output, inserter.lower_bound('a'))` is that correct? – Jonathan Mee Oct 21 '16 at 15:35
  • 1
    @JonathanMee you could. In fact, this would be a good idea. I may have oversimplified saying that the hint is ignored - it's just used to start the search for the correct key, but doesn't guarantee that the element will be inserted before it, because the container has to be sortd. But you could also use `begin(output)` or `end(output)` or any other valid iterator to `output`'s values and it'd work fine - maybe with a little different performance characteristics. – krzaq Oct 21 '16 at 15:38