Accelerated C++ 8.6 exercise

Aug 23, 2017 at 10:19am
Suppose that m has type map<int, string> and that we encounter a call to copy(m.begin(), m.end(), back_inserter(x)). What can we say about the type of x? What if the call were copy(x.begin(), x.end(), back_inserter(m)) instead?

I cannot get an answer. I thought x should be type map<int, string> but I tried and it's impossible because maps don't have push_back. On the other hand if I define x as a vector<int> or a vector<string> I get compilation errors.

Aug 23, 2017 at 10:33am
std::map stores each key-value pair using std::pair.

1
2
3
map<int, string> m;
vector<pair<int, string>> x;
copy(m.begin(), m.end(), back_inserter(x));

Last edited on Aug 23, 2017 at 10:34am
Aug 23, 2017 at 10:40am
Thanks!

The answer to the second question is that is doesn't matter the type of x right? it's impossible to call back_inserter(m) because maps cannot do push_back
Aug 23, 2017 at 10:44am
Hello AwesomeGuy,

Show what code you have done so far. Did you include the header file "iterator"? Based on this page: http://www.cplusplus.com/reference/iterator/back_inserter/?kw=back_inserter It looks like "x" should be a vector.

This is a new concept for me, so it is easier if I have code to work with to figure out what is going wrong. Also any compile error messages would be helpful.

Hope that helps,

Andy

P.S. Just had another thought. It looks like the "std::copy" is on a map with two elements. So if "x" does not have two elements to copy I can see where that would be a problem. The above link shows an example using vectors. Maybe it will not work with a map?
Aug 23, 2017 at 10:58am
AwesomeGuy wrote:
The answer to the second question is that is doesn't matter the type of x right? it's impossible to call back_inserter(m) because maps cannot do push_back

Yes, That's right.
Aug 23, 2017 at 12:11pm
AwesomeGuy wrote:
What can we say about the type of x?
is doesn't matter the type of x right?

Sorry, Peter87, could you please explain me better your answer (or even the question itself)?
If we create an instance of a container, in this case a std::map<int, std::string> but it could be any container, don’t we need to know the type of what we put inside it before trying to put it in, no matter what method we invoke to do the job?

Even if we knew the type only at run-time, something like
std::map<decltype(A), decltype(B)> mymap;
if it’s possible, and we were using the most exotic :) inserting method, aren’t we forced to guarantee the types?
mymap.emplace_hint(something which returns an A, something which returns a B);

I’m afraid I could be totally misunderstanding the point here.
Aug 23, 2017 at 12:51pm
Enoizat, for the second question (What if the call were copy(x.begin(), x.end(), back_inserter(m)) instead?) the expression back_inserter(m) will always give an error because std::map doesn't have a push_back member function. That's why it doesn't matter what the type of x is, because no matter what we choose, it will never make this line of code work.

The types are always known at compile time. Even decltype is evaluated at compile time.
Aug 23, 2017 at 1:13pm
Peter87, thanks a lot for your kind explanation.
Your answer is indeed the proper answer to what AwesomeGuy asked.

@AwesomeGuy, if your wans’t just an academic question and you know what x is, there are workarounds for your code, like the ones described here:
https://stackoverflow.com/questions/18645290/c-std-copying-a-list-to-map

Peter87 wrote:
The types are always known at compile time. Even decltype is evaluated at compile time.

Yes, you are right, the compiler knows the types. Thank you for your correction. I expressed myself terribly.
Topic archived. No new replies allowed.