Assignment in C++ occurs despite exception on the right side
Clash Royale CLAN TAG#URR8PPP
up vote
25
down vote
favorite
I have some (C++14) code that looks like this:
map<int, set<string>> junk;
for (int id : GenerateIds())
try
set<string> stuff = GetStuff();
junk[id] = stuff;
catch (const StuffException& e)
...
This works. Sometimes GetStuff()
throws an exception, which works fine, because if it does, I don't want a value in the junk map then.
But at first I'd written this in the loop, which doesn't work:
junk[id] = GetStuff();
More precisely, even when GetStuff()
throws an exception, junk[id]
is created (and assigned an empty set).
This isn't what I'd expect: I'd expect them to function the same way.
Is there a principle of C++ that I've misunderstood here?
c++ c++14
add a comment |Â
up vote
25
down vote
favorite
I have some (C++14) code that looks like this:
map<int, set<string>> junk;
for (int id : GenerateIds())
try
set<string> stuff = GetStuff();
junk[id] = stuff;
catch (const StuffException& e)
...
This works. Sometimes GetStuff()
throws an exception, which works fine, because if it does, I don't want a value in the junk map then.
But at first I'd written this in the loop, which doesn't work:
junk[id] = GetStuff();
More precisely, even when GetStuff()
throws an exception, junk[id]
is created (and assigned an empty set).
This isn't what I'd expect: I'd expect them to function the same way.
Is there a principle of C++ that I've misunderstood here?
c++ c++14
Also see c++ map exception safe insert and Making operations on standard-library containers strongly exception safe, Exception Safety: Concepts and Techniques, etc.
â jww
7 hours ago
See Order of evaluation of assignment statement in C++ also related Does this code from âÂÂThe C++ Programming Languageâ 4th edition section 36.3.6 have well-defined behavior? and What are the evaluation order guarantees introduced by C++17?
â Shafik Yaghmour
6 hours ago
1
Just to clarify for future readers with similar problems: no assignment happens here.junk[id]
creates a newset
, yes, but that is using the default constructor. That's why the set is empty. This empty set would have been used as the object to assign to, ifGetStuff()
would have succeeded. But the exception thrown is precisely why no assignment happens. The set is left in its default state. It is a proper C++ object, and you can call its members normally. I.e.junk[id].size()
will be 0 afterwards.
â MSalters
4 hours ago
@MSalters Good clarification! I used "assignment" too loosely (but "default constructed" was maybe a bit heavy for the question title ;-).
â jma
4 hours ago
add a comment |Â
up vote
25
down vote
favorite
up vote
25
down vote
favorite
I have some (C++14) code that looks like this:
map<int, set<string>> junk;
for (int id : GenerateIds())
try
set<string> stuff = GetStuff();
junk[id] = stuff;
catch (const StuffException& e)
...
This works. Sometimes GetStuff()
throws an exception, which works fine, because if it does, I don't want a value in the junk map then.
But at first I'd written this in the loop, which doesn't work:
junk[id] = GetStuff();
More precisely, even when GetStuff()
throws an exception, junk[id]
is created (and assigned an empty set).
This isn't what I'd expect: I'd expect them to function the same way.
Is there a principle of C++ that I've misunderstood here?
c++ c++14
I have some (C++14) code that looks like this:
map<int, set<string>> junk;
for (int id : GenerateIds())
try
set<string> stuff = GetStuff();
junk[id] = stuff;
catch (const StuffException& e)
...
This works. Sometimes GetStuff()
throws an exception, which works fine, because if it does, I don't want a value in the junk map then.
But at first I'd written this in the loop, which doesn't work:
junk[id] = GetStuff();
More precisely, even when GetStuff()
throws an exception, junk[id]
is created (and assigned an empty set).
This isn't what I'd expect: I'd expect them to function the same way.
Is there a principle of C++ that I've misunderstood here?
c++ c++14
c++ c++14
edited 17 mins ago
Peter Mortensen
13.2k1983111
13.2k1983111
asked 7 hours ago
jma
1,11311531
1,11311531
Also see c++ map exception safe insert and Making operations on standard-library containers strongly exception safe, Exception Safety: Concepts and Techniques, etc.
â jww
7 hours ago
See Order of evaluation of assignment statement in C++ also related Does this code from âÂÂThe C++ Programming Languageâ 4th edition section 36.3.6 have well-defined behavior? and What are the evaluation order guarantees introduced by C++17?
â Shafik Yaghmour
6 hours ago
1
Just to clarify for future readers with similar problems: no assignment happens here.junk[id]
creates a newset
, yes, but that is using the default constructor. That's why the set is empty. This empty set would have been used as the object to assign to, ifGetStuff()
would have succeeded. But the exception thrown is precisely why no assignment happens. The set is left in its default state. It is a proper C++ object, and you can call its members normally. I.e.junk[id].size()
will be 0 afterwards.
â MSalters
4 hours ago
@MSalters Good clarification! I used "assignment" too loosely (but "default constructed" was maybe a bit heavy for the question title ;-).
â jma
4 hours ago
add a comment |Â
Also see c++ map exception safe insert and Making operations on standard-library containers strongly exception safe, Exception Safety: Concepts and Techniques, etc.
â jww
7 hours ago
See Order of evaluation of assignment statement in C++ also related Does this code from âÂÂThe C++ Programming Languageâ 4th edition section 36.3.6 have well-defined behavior? and What are the evaluation order guarantees introduced by C++17?
â Shafik Yaghmour
6 hours ago
1
Just to clarify for future readers with similar problems: no assignment happens here.junk[id]
creates a newset
, yes, but that is using the default constructor. That's why the set is empty. This empty set would have been used as the object to assign to, ifGetStuff()
would have succeeded. But the exception thrown is precisely why no assignment happens. The set is left in its default state. It is a proper C++ object, and you can call its members normally. I.e.junk[id].size()
will be 0 afterwards.
â MSalters
4 hours ago
@MSalters Good clarification! I used "assignment" too loosely (but "default constructed" was maybe a bit heavy for the question title ;-).
â jma
4 hours ago
Also see c++ map exception safe insert and Making operations on standard-library containers strongly exception safe, Exception Safety: Concepts and Techniques, etc.
â jww
7 hours ago
Also see c++ map exception safe insert and Making operations on standard-library containers strongly exception safe, Exception Safety: Concepts and Techniques, etc.
â jww
7 hours ago
See Order of evaluation of assignment statement in C++ also related Does this code from âÂÂThe C++ Programming Languageâ 4th edition section 36.3.6 have well-defined behavior? and What are the evaluation order guarantees introduced by C++17?
â Shafik Yaghmour
6 hours ago
See Order of evaluation of assignment statement in C++ also related Does this code from âÂÂThe C++ Programming Languageâ 4th edition section 36.3.6 have well-defined behavior? and What are the evaluation order guarantees introduced by C++17?
â Shafik Yaghmour
6 hours ago
1
1
Just to clarify for future readers with similar problems: no assignment happens here.
junk[id]
creates a new set
, yes, but that is using the default constructor. That's why the set is empty. This empty set would have been used as the object to assign to, if GetStuff()
would have succeeded. But the exception thrown is precisely why no assignment happens. The set is left in its default state. It is a proper C++ object, and you can call its members normally. I.e. junk[id].size()
will be 0 afterwards.â MSalters
4 hours ago
Just to clarify for future readers with similar problems: no assignment happens here.
junk[id]
creates a new set
, yes, but that is using the default constructor. That's why the set is empty. This empty set would have been used as the object to assign to, if GetStuff()
would have succeeded. But the exception thrown is precisely why no assignment happens. The set is left in its default state. It is a proper C++ object, and you can call its members normally. I.e. junk[id].size()
will be 0 afterwards.â MSalters
4 hours ago
@MSalters Good clarification! I used "assignment" too loosely (but "default constructed" was maybe a bit heavy for the question title ;-).
â jma
4 hours ago
@MSalters Good clarification! I used "assignment" too loosely (but "default constructed" was maybe a bit heavy for the question title ;-).
â jma
4 hours ago
add a comment |Â
3 Answers
3
active
oldest
votes
up vote
40
down vote
accepted
Before C++17 there was no sequencing between the left- and right-hand side of overloaded 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 implementation-defined, which means your compiler performs the evaluation of the left-hand side first.
See this evaluation order reference for more details (especially point 20).
1
If I understand the reference correctly the first sentence in the answer could be shortened by removing "overloaded", as right-hand-side is evaluated first for both overloaded and non-overloaded assignment operators in C++17.
â Hans Olsson
6 hours ago
7
"That means the evaluation order is implementation-defined". Isn't it more correct to say that "evaluation order is unspecified in C++14 and before"?
â geza
5 hours ago
add a comment |Â
up vote
7
down vote
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.
2
You're missing the part that explains why this happens even if the RHS throws.
â juanchopanza
7 hours ago
Is it guaranteed that the key is created if the RHS throws?
â perreal
7 hours ago
@juanchopanza "junk[id] causes this" was referring to the text I quoted and "and then GetStuff() throws" was referring to what happens after the insertion has already taken place. Perhaps I could been clearer. Will edit.
â Ted Lyngmo
7 hours ago
1
@perreal No, see Some programmer dudes answer.
â Ted Lyngmo
7 hours ago
1
@TedLyngmo Much better, thanks!
â juanchopanza
6 hours ago
 |Â
show 4 more comments
up vote
0
down vote
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.
3
i dont think there is any misconception about howoperator
works involved here. Also from your answer its not clear whyoperator=
evaluates the left hand side, even if the right hand side throws an exception
â user463035818
7 hours ago
If there is any misunderstanding, it would for me be a misunderstanding for a[b]=...; not just for a[...].
â Hans Olsson
5 hours ago
@user463035818: The questioner expresses a belief that an assignment occurred, which strongly suggests they are unaware that evaluating theoperator
would create an empty set forjunk[id]
on its own.
â user2357112
2 hours ago
add a comment |Â
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
40
down vote
accepted
Before C++17 there was no sequencing between the left- and right-hand side of overloaded 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 implementation-defined, which means your compiler performs the evaluation of the left-hand side first.
See this evaluation order reference for more details (especially point 20).
1
If I understand the reference correctly the first sentence in the answer could be shortened by removing "overloaded", as right-hand-side is evaluated first for both overloaded and non-overloaded assignment operators in C++17.
â Hans Olsson
6 hours ago
7
"That means the evaluation order is implementation-defined". Isn't it more correct to say that "evaluation order is unspecified in C++14 and before"?
â geza
5 hours ago
add a comment |Â
up vote
40
down vote
accepted
Before C++17 there was no sequencing between the left- and right-hand side of overloaded 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 implementation-defined, which means your compiler performs the evaluation of the left-hand side first.
See this evaluation order reference for more details (especially point 20).
1
If I understand the reference correctly the first sentence in the answer could be shortened by removing "overloaded", as right-hand-side is evaluated first for both overloaded and non-overloaded assignment operators in C++17.
â Hans Olsson
6 hours ago
7
"That means the evaluation order is implementation-defined". Isn't it more correct to say that "evaluation order is unspecified in C++14 and before"?
â geza
5 hours ago
add a comment |Â
up vote
40
down vote
accepted
up vote
40
down vote
accepted
Before C++17 there was no sequencing between the left- and right-hand side of overloaded 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 implementation-defined, which means your compiler performs the evaluation of the left-hand side first.
See this evaluation order reference for more details (especially point 20).
Before C++17 there was no sequencing between the left- and right-hand side of overloaded 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 implementation-defined, which means your compiler performs the evaluation of the left-hand side first.
See this evaluation order reference for more details (especially point 20).
answered 7 hours ago
Some programmer dude
288k24239398
288k24239398
1
If I understand the reference correctly the first sentence in the answer could be shortened by removing "overloaded", as right-hand-side is evaluated first for both overloaded and non-overloaded assignment operators in C++17.
â Hans Olsson
6 hours ago
7
"That means the evaluation order is implementation-defined". Isn't it more correct to say that "evaluation order is unspecified in C++14 and before"?
â geza
5 hours ago
add a comment |Â
1
If I understand the reference correctly the first sentence in the answer could be shortened by removing "overloaded", as right-hand-side is evaluated first for both overloaded and non-overloaded assignment operators in C++17.
â Hans Olsson
6 hours ago
7
"That means the evaluation order is implementation-defined". Isn't it more correct to say that "evaluation order is unspecified in C++14 and before"?
â geza
5 hours ago
1
1
If I understand the reference correctly the first sentence in the answer could be shortened by removing "overloaded", as right-hand-side is evaluated first for both overloaded and non-overloaded assignment operators in C++17.
â Hans Olsson
6 hours ago
If I understand the reference correctly the first sentence in the answer could be shortened by removing "overloaded", as right-hand-side is evaluated first for both overloaded and non-overloaded assignment operators in C++17.
â Hans Olsson
6 hours ago
7
7
"That means the evaluation order is implementation-defined". Isn't it more correct to say that "evaluation order is unspecified in C++14 and before"?
â geza
5 hours ago
"That means the evaluation order is implementation-defined". Isn't it more correct to say that "evaluation order is unspecified in C++14 and before"?
â geza
5 hours ago
add a comment |Â
up vote
7
down vote
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.
2
You're missing the part that explains why this happens even if the RHS throws.
â juanchopanza
7 hours ago
Is it guaranteed that the key is created if the RHS throws?
â perreal
7 hours ago
@juanchopanza "junk[id] causes this" was referring to the text I quoted and "and then GetStuff() throws" was referring to what happens after the insertion has already taken place. Perhaps I could been clearer. Will edit.
â Ted Lyngmo
7 hours ago
1
@perreal No, see Some programmer dudes answer.
â Ted Lyngmo
7 hours ago
1
@TedLyngmo Much better, thanks!
â juanchopanza
6 hours ago
 |Â
show 4 more comments
up vote
7
down vote
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.
2
You're missing the part that explains why this happens even if the RHS throws.
â juanchopanza
7 hours ago
Is it guaranteed that the key is created if the RHS throws?
â perreal
7 hours ago
@juanchopanza "junk[id] causes this" was referring to the text I quoted and "and then GetStuff() throws" was referring to what happens after the insertion has already taken place. Perhaps I could been clearer. Will edit.
â Ted Lyngmo
7 hours ago
1
@perreal No, see Some programmer dudes answer.
â Ted Lyngmo
7 hours ago
1
@TedLyngmo Much better, thanks!
â juanchopanza
6 hours ago
 |Â
show 4 more comments
up vote
7
down vote
up vote
7
down vote
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.
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.
edited 6 hours ago
answered 7 hours ago
Ted Lyngmo
36915
36915
2
You're missing the part that explains why this happens even if the RHS throws.
â juanchopanza
7 hours ago
Is it guaranteed that the key is created if the RHS throws?
â perreal
7 hours ago
@juanchopanza "junk[id] causes this" was referring to the text I quoted and "and then GetStuff() throws" was referring to what happens after the insertion has already taken place. Perhaps I could been clearer. Will edit.
â Ted Lyngmo
7 hours ago
1
@perreal No, see Some programmer dudes answer.
â Ted Lyngmo
7 hours ago
1
@TedLyngmo Much better, thanks!
â juanchopanza
6 hours ago
 |Â
show 4 more comments
2
You're missing the part that explains why this happens even if the RHS throws.
â juanchopanza
7 hours ago
Is it guaranteed that the key is created if the RHS throws?
â perreal
7 hours ago
@juanchopanza "junk[id] causes this" was referring to the text I quoted and "and then GetStuff() throws" was referring to what happens after the insertion has already taken place. Perhaps I could been clearer. Will edit.
â Ted Lyngmo
7 hours ago
1
@perreal No, see Some programmer dudes answer.
â Ted Lyngmo
7 hours ago
1
@TedLyngmo Much better, thanks!
â juanchopanza
6 hours ago
2
2
You're missing the part that explains why this happens even if the RHS throws.
â juanchopanza
7 hours ago
You're missing the part that explains why this happens even if the RHS throws.
â juanchopanza
7 hours ago
Is it guaranteed that the key is created if the RHS throws?
â perreal
7 hours ago
Is it guaranteed that the key is created if the RHS throws?
â perreal
7 hours ago
@juanchopanza "junk[id] causes this" was referring to the text I quoted and "and then GetStuff() throws" was referring to what happens after the insertion has already taken place. Perhaps I could been clearer. Will edit.
â Ted Lyngmo
7 hours ago
@juanchopanza "junk[id] causes this" was referring to the text I quoted and "and then GetStuff() throws" was referring to what happens after the insertion has already taken place. Perhaps I could been clearer. Will edit.
â Ted Lyngmo
7 hours ago
1
1
@perreal No, see Some programmer dudes answer.
â Ted Lyngmo
7 hours ago
@perreal No, see Some programmer dudes answer.
â Ted Lyngmo
7 hours ago
1
1
@TedLyngmo Much better, thanks!
â juanchopanza
6 hours ago
@TedLyngmo Much better, thanks!
â juanchopanza
6 hours ago
 |Â
show 4 more comments
up vote
0
down vote
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.
3
i dont think there is any misconception about howoperator
works involved here. Also from your answer its not clear whyoperator=
evaluates the left hand side, even if the right hand side throws an exception
â user463035818
7 hours ago
If there is any misunderstanding, it would for me be a misunderstanding for a[b]=...; not just for a[...].
â Hans Olsson
5 hours ago
@user463035818: The questioner expresses a belief that an assignment occurred, which strongly suggests they are unaware that evaluating theoperator
would create an empty set forjunk[id]
on its own.
â user2357112
2 hours ago
add a comment |Â
up vote
0
down vote
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.
3
i dont think there is any misconception about howoperator
works involved here. Also from your answer its not clear whyoperator=
evaluates the left hand side, even if the right hand side throws an exception
â user463035818
7 hours ago
If there is any misunderstanding, it would for me be a misunderstanding for a[b]=...; not just for a[...].
â Hans Olsson
5 hours ago
@user463035818: The questioner expresses a belief that an assignment occurred, which strongly suggests they are unaware that evaluating theoperator
would create an empty set forjunk[id]
on its own.
â user2357112
2 hours ago
add a comment |Â
up vote
0
down vote
up vote
0
down vote
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.
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.
answered 7 hours ago
paddy
41.2k52874
41.2k52874
3
i dont think there is any misconception about howoperator
works involved here. Also from your answer its not clear whyoperator=
evaluates the left hand side, even if the right hand side throws an exception
â user463035818
7 hours ago
If there is any misunderstanding, it would for me be a misunderstanding for a[b]=...; not just for a[...].
â Hans Olsson
5 hours ago
@user463035818: The questioner expresses a belief that an assignment occurred, which strongly suggests they are unaware that evaluating theoperator
would create an empty set forjunk[id]
on its own.
â user2357112
2 hours ago
add a comment |Â
3
i dont think there is any misconception about howoperator
works involved here. Also from your answer its not clear whyoperator=
evaluates the left hand side, even if the right hand side throws an exception
â user463035818
7 hours ago
If there is any misunderstanding, it would for me be a misunderstanding for a[b]=...; not just for a[...].
â Hans Olsson
5 hours ago
@user463035818: The questioner expresses a belief that an assignment occurred, which strongly suggests they are unaware that evaluating theoperator
would create an empty set forjunk[id]
on its own.
â user2357112
2 hours ago
3
3
i dont think there is any misconception about how
operator
works involved here. Also from your answer its not clear why operator=
evaluates the left hand side, even if the right hand side throws an exceptionâ user463035818
7 hours ago
i dont think there is any misconception about how
operator
works involved here. Also from your answer its not clear why operator=
evaluates the left hand side, even if the right hand side throws an exceptionâ user463035818
7 hours ago
If there is any misunderstanding, it would for me be a misunderstanding for a[b]=...; not just for a[...].
â Hans Olsson
5 hours ago
If there is any misunderstanding, it would for me be a misunderstanding for a[b]=...; not just for a[...].
â Hans Olsson
5 hours ago
@user463035818: The questioner expresses a belief that an assignment occurred, which strongly suggests they are unaware that evaluating the
operator
would create an empty set for junk[id]
on its own.â user2357112
2 hours ago
@user463035818: The questioner expresses a belief that an assignment occurred, which strongly suggests they are unaware that evaluating the
operator
would create an empty set for junk[id]
on its own.â user2357112
2 hours ago
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53154843%2fassignment-in-c-occurs-despite-exception-on-the-right-side%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Also see c++ map exception safe insert and Making operations on standard-library containers strongly exception safe, Exception Safety: Concepts and Techniques, etc.
â jww
7 hours ago
See Order of evaluation of assignment statement in C++ also related Does this code from âÂÂThe C++ Programming Languageâ 4th edition section 36.3.6 have well-defined behavior? and What are the evaluation order guarantees introduced by C++17?
â Shafik Yaghmour
6 hours ago
1
Just to clarify for future readers with similar problems: no assignment happens here.
junk[id]
creates a newset
, yes, but that is using the default constructor. That's why the set is empty. This empty set would have been used as the object to assign to, ifGetStuff()
would have succeeded. But the exception thrown is precisely why no assignment happens. The set is left in its default state. It is a proper C++ object, and you can call its members normally. I.e.junk[id].size()
will be 0 afterwards.â MSalters
4 hours ago
@MSalters Good clarification! I used "assignment" too loosely (but "default constructed" was maybe a bit heavy for the question title ;-).
â jma
4 hours ago