modules - wiki c++ 20




Atribuição em C++ ocorre apesar de exceção no lado direito (2)

Eu tenho alguns (C + + 14) código que se parece com isso:

map<int, set<string>> junk;
for (int id : GenerateIds()) {
    try {
        set<string> stuff = GetStuff();
        junk[id] = stuff;
    } catch (const StuffException& e) {
        ...
    }
}

Isso funciona. Às vezes GetStuff() lança uma exceção, que funciona bem, porque se isso acontecer, eu não quero um valor no mapa de lixo eletrônico.

Mas no começo eu escrevi isso no loop, o que não funciona:

junk[id] = GetStuff();

Mais precisamente, mesmo quando GetStuff() lança uma exceção, o junk[id] é criado (e atribuído um conjunto vazio).

Isso não é o que eu esperaria: espero que funcionem da mesma maneira.

Existe um princípio de C ++ que eu entendi mal aqui?


std :: map :: operator []

Retorna uma referência ao valor mapeado para uma chave equivalente à chave, realizando uma inserção se essa chave ainda não existir.

junk[id] faz com que a inserção acima mencionada e depois que já aconteceu GetStuff() lança. Note que em C ++ 14 a ordem na qual estas coisas acontecem é implementação definida assim com um compilador diferente seu junk[id] = GetStuff(); pode não fazer a inserção se GetStuff() lançar.


Antes do C ++ 17, não havia sequenciamento entre o lado esquerdo e o lado direito dos operadores de atribuição.

É o primeiro em C ++ 17 que o sequenciamento explícito foi introduzido (o lado direito é avaliado primeiro).

Isso significa que a ordem de avaliação não é especificada , o que significa que cabe à implementação realizar a avaliação na ordem em que deseja e, nesse caso, avalia o lado esquerdo primeiro.

Veja esta referência de ordem de avaliação para mais detalhes (especialmente o ponto 20).







c++14