Assignment in C++ occurs despite exception on the right side

前端 未结 3 1321
遥遥无期
遥遥无期 2021-02-03 17:05

I have some (C++14) code that looks like this:

map> junk;
for (int id : GenerateIds()) {
    try {
        set stuff =         


        
相关标签:
3条回答
  • 2021-02-03 17:09

    You're misunderstanding how operator[] works on std::map.

    It returns a reference to the mapped item. Therefore, your code is first inserting a default item in that position and then invoking operator= to set a new value.

    To make this work the way you expect, you'll need to use std::map::insert (*):

    junk.insert(std::make_pair(id, GetStuff()));
    

    Caveat: insert will only add the value if id is not already mapped.

    0 讨论(0)
  • 2021-02-03 17:26

    Before C++17 there was no sequencing between the left- and right-hand side of assignment operators.

    It's first in C++17 that explicit sequencing was introduced (right-hand side is evaluated first).

    That means the evaluation order is unspecified, which means it's up to the implementation to perform the evaluation in the order in which it wants, and in this case it evaluates the left-hand side first.

    See this evaluation order reference for more details (especially point 20).

    0 讨论(0)
  • 2021-02-03 17:31

    std::map::operator[]

    Returns a reference to the value that is mapped to a key equivalent to key, performing an insertion if such key does not already exist.

    junk[id] causes the above mentioned insertion and after that has already happened GetStuff() throws. Note that in C++14 the order in which these things happen is implementation defined so with a different compiler your junk[id] = GetStuff(); may not do the insertion if GetStuff() throws.

    0 讨论(0)
提交回复
热议问题