How is std::optional never “valueless by exception”?How do you set, clear, and toggle a single bit?How to concatenate a std::string and an int?What's the best way to trim std::string?How do I iterate over the words of a string?How to convert std::string to lower case?How to convert a std::string to const char* or char*?How can I profile C++ code running on Linux?std::wstring VS std::stringWhy is “using namespace std;” considered bad practice?Am I abusing std::optional

Why does a sticker slowly peel off, but if it is pulled quickly it tears?

What ways are there to "PEEK" memory sections in (different) BASIC(s)

How do I portray irrational anger in first person?

Do multi-engine jets need all engines with equal age to reduce asymmetry in thrust and fuel consumption arising out of deterioration?

To what extent should we fear giving offense?

How to handle inventory and story of a player leaving

Was the six engine Boeing-747 ever thought about?

Why does the weaker C–H bond have a higher wavenumber than the C=O bond?

Should I ask for a raise one month before the end of an internship?

How to prevent a hosting company from accessing a VM's encryption keys?

Did the Apollo Guidance Computer really use 60% of the world's ICs in 1963?

Why is there not a willingness from the world to step in between Pakistan and India?

Why did the population of Bhutan drop by 70% between 2007 and 2008?

How does attacking during a conversation affect initiative?

Can I lend a small amount of my own money to a bank at the federal funds rate?

What to do about my 1-month-old boy peeing through diapers?

Why did Lucius make a deal out of Buckbeak hurting Draco but not about Draco being turned into a ferret?

Why does this London Underground poster from 1924 have a Star of David atop a Christmas tree?

Is it unusual for a math department not to have a mail/web server?

Heat output from a 200W electric radiator?

Why can't you say don't instead of won't?

Looking for a plural noun related to ‘fulcrum’ or ‘pivot’ that denotes multiple things as crucial to success

Group riding etiquette

Alternatives to Network Backup



How is std::optional never “valueless by exception”?


How do you set, clear, and toggle a single bit?How to concatenate a std::string and an int?What's the best way to trim std::string?How do I iterate over the words of a string?How to convert std::string to lower case?How to convert a std::string to const char* or char*?How can I profile C++ code running on Linux?std::wstring VS std::stringWhy is “using namespace std;” considered bad practice?Am I abusing std::optional






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








6















std::variant can enter a state called "valueless by exception".



As I understand, the common cause of this is if a move assignment throws an exception. The variant's old value isn't guaranteed to be present anymore, and neither is the intended new value.



std::optional, however, doesn't have such a state. cppreference makes the bold claim:




If an exception is thrown, the initialization state of *this ... is unchanged, i.e. if the object contained a value, it still contains a value, and the other way round.




How is std::optional able to avoid becoming "valueless by exception", while std::variant is not?










share|improve this question






























    6















    std::variant can enter a state called "valueless by exception".



    As I understand, the common cause of this is if a move assignment throws an exception. The variant's old value isn't guaranteed to be present anymore, and neither is the intended new value.



    std::optional, however, doesn't have such a state. cppreference makes the bold claim:




    If an exception is thrown, the initialization state of *this ... is unchanged, i.e. if the object contained a value, it still contains a value, and the other way round.




    How is std::optional able to avoid becoming "valueless by exception", while std::variant is not?










    share|improve this question


























      6












      6








      6


      1






      std::variant can enter a state called "valueless by exception".



      As I understand, the common cause of this is if a move assignment throws an exception. The variant's old value isn't guaranteed to be present anymore, and neither is the intended new value.



      std::optional, however, doesn't have such a state. cppreference makes the bold claim:




      If an exception is thrown, the initialization state of *this ... is unchanged, i.e. if the object contained a value, it still contains a value, and the other way round.




      How is std::optional able to avoid becoming "valueless by exception", while std::variant is not?










      share|improve this question














      std::variant can enter a state called "valueless by exception".



      As I understand, the common cause of this is if a move assignment throws an exception. The variant's old value isn't guaranteed to be present anymore, and neither is the intended new value.



      std::optional, however, doesn't have such a state. cppreference makes the bold claim:




      If an exception is thrown, the initialization state of *this ... is unchanged, i.e. if the object contained a value, it still contains a value, and the other way round.




      How is std::optional able to avoid becoming "valueless by exception", while std::variant is not?







      c++ c++17 stdoptional std-variant






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked 8 hours ago









      Drew DormannDrew Dormann

      42.8k9 gold badges87 silver badges144 bronze badges




      42.8k9 gold badges87 silver badges144 bronze badges

























          3 Answers
          3






          active

          oldest

          votes


















          10















          optional<T> has one of two states:



          • a T

          • empty

          A variant can only enter the valueless state when transitioning from one state to another if transitioning will throw - because you need to somehow recover the original object and the various strategies for doing so require either extra storage1, heap allocation2, or an empty state3.



          But for optional, transitioning from T to empty is just a destruction. So that only throws if T's destructor throws, and really who cares at that point. And transitioning from empty to T is not an issue - if that throws, it's easy to recover the original object: the empty state is empty.



          The challenging case is: emplace() when we already had a T. We necessarily need to have destroyed the original object, so what do we do if the emplace construction throws? With optional, we have a known, convenient empty state to fallback to - so the design is just to do that.



          variant's problems from not having that easy state to recover to.




          1 As boost::variant2 does.
          2 As boost::variant does.
          3 I'm not sure of a variant implementation that does this, but there was a design suggestion that variant<monostate, A, B> could transition into the monostate state if it held an A and the transition to B threw.






          share|improve this answer



























          • "and really who cares at that point" aka nasal demons.

            – T.C.
            8 hours ago











          • I don't see how this answer addresses the case of an optional<T> going from T to a different T state. Note that emplace and operator= have different behavior here in the case of an exception being thrown in the process!

            – Max Langhof
            8 hours ago












          • @MaxLanghof: If the constructor throws in emplace, then the optional is explicitly stated to be unengaged. If operator= throws during construction, then there's similarly no value. Barry's point remains valid: it works because there is always a legitimate empty state that the optional can go to. variant doesn't have that luxury because variant cannot be empty.

            – Nicol Bolas
            7 hours ago












          • @NicolBolas The difficult case (and the one most similar to the variant problem) is assigning a new value when you have an existing one. And the core of retaining the initialization state is using T::operator= - this specific case involves no empty optional and no destructor at all. Since all the cases covered in this answer regarding std::optional involve either destruction or empty states, I think this important case (covered by the other answers) is missing. Don't get me wrong, this answer covers all the other aspects just fine, but I had to read up on this last case myself...

            – Max Langhof
            7 hours ago



















          7















          std::optional has it easy:



          1. It contains a value and a new value is assigned:

            Easy, just delegate to the assignment operator and let it deal with it. Even in the case of an exception, there will still be a value left.


          2. It contains a value and the value is removed:

            Easy, the dtor must not throw. The standard library generally assumes that for user-defined types.


          3. It contains no value and one is assigned:

            Reverting to no value in the face of an exception on constructing is simple enough.


          4. It contains no value and no value is assigned:

            Trivial.


          std::variant has the same easy time when the type stored does not change.

          Unfortunately, when a different type is assigned it must make place for it by destroying the previous value, and then constructing the new value might throw!



          As the previous value is already lost, what can you do?

          Mark it as valueless by exception to have a stable, valid though undesirable state, and let the exception propagate.



          One could use extra space and time to allocate the values dynamically, save the old value somewhere temporarily, construct the new value before assigning or the like, but all those strategies are costly, and only the first always works.






          share|improve this answer


































            4















            "valueless by exception" refers to a specific scenario where you need to change the type stored in the variant. That necessarily requires 1) destroying the old value and then 2) creating the new one in its place. If 2) fails, you have no way to go back (without undue overhead unacceptable to the committee).



            optional doesn't have this problem. If some operation on the object it contains throws an exception, so be it. The object is still there. That doesn't mean that the object's state is still meaningful - it's whatever the throwing operation leaves it in. Hopefully that operation has at least the basic guarantee.






            share|improve this answer



























            • "the initialization state of *this is unchanged" ... am I misunderstanding that statement? I think you're saying that it could change to something not meaningful.

              – Drew Dormann
              8 hours ago






            • 1





              From optional's perspective, it's still holding an object. Whether that object is in a usable state is not optional's concern.

              – T.C.
              8 hours ago











            • It is quite an important detail that std::optional::operator= uses T::operator= instead of destroying + constructing the T value. emplace does the latter (and leaves the optional empty if construction of the new value throws).

              – Max Langhof
              8 hours ago














            Your Answer






            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "1"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f57696187%2fhow-is-stdoptional-never-valueless-by-exception%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            10















            optional<T> has one of two states:



            • a T

            • empty

            A variant can only enter the valueless state when transitioning from one state to another if transitioning will throw - because you need to somehow recover the original object and the various strategies for doing so require either extra storage1, heap allocation2, or an empty state3.



            But for optional, transitioning from T to empty is just a destruction. So that only throws if T's destructor throws, and really who cares at that point. And transitioning from empty to T is not an issue - if that throws, it's easy to recover the original object: the empty state is empty.



            The challenging case is: emplace() when we already had a T. We necessarily need to have destroyed the original object, so what do we do if the emplace construction throws? With optional, we have a known, convenient empty state to fallback to - so the design is just to do that.



            variant's problems from not having that easy state to recover to.




            1 As boost::variant2 does.
            2 As boost::variant does.
            3 I'm not sure of a variant implementation that does this, but there was a design suggestion that variant<monostate, A, B> could transition into the monostate state if it held an A and the transition to B threw.






            share|improve this answer



























            • "and really who cares at that point" aka nasal demons.

              – T.C.
              8 hours ago











            • I don't see how this answer addresses the case of an optional<T> going from T to a different T state. Note that emplace and operator= have different behavior here in the case of an exception being thrown in the process!

              – Max Langhof
              8 hours ago












            • @MaxLanghof: If the constructor throws in emplace, then the optional is explicitly stated to be unengaged. If operator= throws during construction, then there's similarly no value. Barry's point remains valid: it works because there is always a legitimate empty state that the optional can go to. variant doesn't have that luxury because variant cannot be empty.

              – Nicol Bolas
              7 hours ago












            • @NicolBolas The difficult case (and the one most similar to the variant problem) is assigning a new value when you have an existing one. And the core of retaining the initialization state is using T::operator= - this specific case involves no empty optional and no destructor at all. Since all the cases covered in this answer regarding std::optional involve either destruction or empty states, I think this important case (covered by the other answers) is missing. Don't get me wrong, this answer covers all the other aspects just fine, but I had to read up on this last case myself...

              – Max Langhof
              7 hours ago
















            10















            optional<T> has one of two states:



            • a T

            • empty

            A variant can only enter the valueless state when transitioning from one state to another if transitioning will throw - because you need to somehow recover the original object and the various strategies for doing so require either extra storage1, heap allocation2, or an empty state3.



            But for optional, transitioning from T to empty is just a destruction. So that only throws if T's destructor throws, and really who cares at that point. And transitioning from empty to T is not an issue - if that throws, it's easy to recover the original object: the empty state is empty.



            The challenging case is: emplace() when we already had a T. We necessarily need to have destroyed the original object, so what do we do if the emplace construction throws? With optional, we have a known, convenient empty state to fallback to - so the design is just to do that.



            variant's problems from not having that easy state to recover to.




            1 As boost::variant2 does.
            2 As boost::variant does.
            3 I'm not sure of a variant implementation that does this, but there was a design suggestion that variant<monostate, A, B> could transition into the monostate state if it held an A and the transition to B threw.






            share|improve this answer



























            • "and really who cares at that point" aka nasal demons.

              – T.C.
              8 hours ago











            • I don't see how this answer addresses the case of an optional<T> going from T to a different T state. Note that emplace and operator= have different behavior here in the case of an exception being thrown in the process!

              – Max Langhof
              8 hours ago












            • @MaxLanghof: If the constructor throws in emplace, then the optional is explicitly stated to be unengaged. If operator= throws during construction, then there's similarly no value. Barry's point remains valid: it works because there is always a legitimate empty state that the optional can go to. variant doesn't have that luxury because variant cannot be empty.

              – Nicol Bolas
              7 hours ago












            • @NicolBolas The difficult case (and the one most similar to the variant problem) is assigning a new value when you have an existing one. And the core of retaining the initialization state is using T::operator= - this specific case involves no empty optional and no destructor at all. Since all the cases covered in this answer regarding std::optional involve either destruction or empty states, I think this important case (covered by the other answers) is missing. Don't get me wrong, this answer covers all the other aspects just fine, but I had to read up on this last case myself...

              – Max Langhof
              7 hours ago














            10














            10










            10









            optional<T> has one of two states:



            • a T

            • empty

            A variant can only enter the valueless state when transitioning from one state to another if transitioning will throw - because you need to somehow recover the original object and the various strategies for doing so require either extra storage1, heap allocation2, or an empty state3.



            But for optional, transitioning from T to empty is just a destruction. So that only throws if T's destructor throws, and really who cares at that point. And transitioning from empty to T is not an issue - if that throws, it's easy to recover the original object: the empty state is empty.



            The challenging case is: emplace() when we already had a T. We necessarily need to have destroyed the original object, so what do we do if the emplace construction throws? With optional, we have a known, convenient empty state to fallback to - so the design is just to do that.



            variant's problems from not having that easy state to recover to.




            1 As boost::variant2 does.
            2 As boost::variant does.
            3 I'm not sure of a variant implementation that does this, but there was a design suggestion that variant<monostate, A, B> could transition into the monostate state if it held an A and the transition to B threw.






            share|improve this answer















            optional<T> has one of two states:



            • a T

            • empty

            A variant can only enter the valueless state when transitioning from one state to another if transitioning will throw - because you need to somehow recover the original object and the various strategies for doing so require either extra storage1, heap allocation2, or an empty state3.



            But for optional, transitioning from T to empty is just a destruction. So that only throws if T's destructor throws, and really who cares at that point. And transitioning from empty to T is not an issue - if that throws, it's easy to recover the original object: the empty state is empty.



            The challenging case is: emplace() when we already had a T. We necessarily need to have destroyed the original object, so what do we do if the emplace construction throws? With optional, we have a known, convenient empty state to fallback to - so the design is just to do that.



            variant's problems from not having that easy state to recover to.




            1 As boost::variant2 does.
            2 As boost::variant does.
            3 I'm not sure of a variant implementation that does this, but there was a design suggestion that variant<monostate, A, B> could transition into the monostate state if it held an A and the transition to B threw.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited 7 hours ago

























            answered 8 hours ago









            BarryBarry

            198k22 gold badges368 silver badges659 bronze badges




            198k22 gold badges368 silver badges659 bronze badges















            • "and really who cares at that point" aka nasal demons.

              – T.C.
              8 hours ago











            • I don't see how this answer addresses the case of an optional<T> going from T to a different T state. Note that emplace and operator= have different behavior here in the case of an exception being thrown in the process!

              – Max Langhof
              8 hours ago












            • @MaxLanghof: If the constructor throws in emplace, then the optional is explicitly stated to be unengaged. If operator= throws during construction, then there's similarly no value. Barry's point remains valid: it works because there is always a legitimate empty state that the optional can go to. variant doesn't have that luxury because variant cannot be empty.

              – Nicol Bolas
              7 hours ago












            • @NicolBolas The difficult case (and the one most similar to the variant problem) is assigning a new value when you have an existing one. And the core of retaining the initialization state is using T::operator= - this specific case involves no empty optional and no destructor at all. Since all the cases covered in this answer regarding std::optional involve either destruction or empty states, I think this important case (covered by the other answers) is missing. Don't get me wrong, this answer covers all the other aspects just fine, but I had to read up on this last case myself...

              – Max Langhof
              7 hours ago


















            • "and really who cares at that point" aka nasal demons.

              – T.C.
              8 hours ago











            • I don't see how this answer addresses the case of an optional<T> going from T to a different T state. Note that emplace and operator= have different behavior here in the case of an exception being thrown in the process!

              – Max Langhof
              8 hours ago












            • @MaxLanghof: If the constructor throws in emplace, then the optional is explicitly stated to be unengaged. If operator= throws during construction, then there's similarly no value. Barry's point remains valid: it works because there is always a legitimate empty state that the optional can go to. variant doesn't have that luxury because variant cannot be empty.

              – Nicol Bolas
              7 hours ago












            • @NicolBolas The difficult case (and the one most similar to the variant problem) is assigning a new value when you have an existing one. And the core of retaining the initialization state is using T::operator= - this specific case involves no empty optional and no destructor at all. Since all the cases covered in this answer regarding std::optional involve either destruction or empty states, I think this important case (covered by the other answers) is missing. Don't get me wrong, this answer covers all the other aspects just fine, but I had to read up on this last case myself...

              – Max Langhof
              7 hours ago

















            "and really who cares at that point" aka nasal demons.

            – T.C.
            8 hours ago





            "and really who cares at that point" aka nasal demons.

            – T.C.
            8 hours ago













            I don't see how this answer addresses the case of an optional<T> going from T to a different T state. Note that emplace and operator= have different behavior here in the case of an exception being thrown in the process!

            – Max Langhof
            8 hours ago






            I don't see how this answer addresses the case of an optional<T> going from T to a different T state. Note that emplace and operator= have different behavior here in the case of an exception being thrown in the process!

            – Max Langhof
            8 hours ago














            @MaxLanghof: If the constructor throws in emplace, then the optional is explicitly stated to be unengaged. If operator= throws during construction, then there's similarly no value. Barry's point remains valid: it works because there is always a legitimate empty state that the optional can go to. variant doesn't have that luxury because variant cannot be empty.

            – Nicol Bolas
            7 hours ago






            @MaxLanghof: If the constructor throws in emplace, then the optional is explicitly stated to be unengaged. If operator= throws during construction, then there's similarly no value. Barry's point remains valid: it works because there is always a legitimate empty state that the optional can go to. variant doesn't have that luxury because variant cannot be empty.

            – Nicol Bolas
            7 hours ago














            @NicolBolas The difficult case (and the one most similar to the variant problem) is assigning a new value when you have an existing one. And the core of retaining the initialization state is using T::operator= - this specific case involves no empty optional and no destructor at all. Since all the cases covered in this answer regarding std::optional involve either destruction or empty states, I think this important case (covered by the other answers) is missing. Don't get me wrong, this answer covers all the other aspects just fine, but I had to read up on this last case myself...

            – Max Langhof
            7 hours ago






            @NicolBolas The difficult case (and the one most similar to the variant problem) is assigning a new value when you have an existing one. And the core of retaining the initialization state is using T::operator= - this specific case involves no empty optional and no destructor at all. Since all the cases covered in this answer regarding std::optional involve either destruction or empty states, I think this important case (covered by the other answers) is missing. Don't get me wrong, this answer covers all the other aspects just fine, but I had to read up on this last case myself...

            – Max Langhof
            7 hours ago














            7















            std::optional has it easy:



            1. It contains a value and a new value is assigned:

              Easy, just delegate to the assignment operator and let it deal with it. Even in the case of an exception, there will still be a value left.


            2. It contains a value and the value is removed:

              Easy, the dtor must not throw. The standard library generally assumes that for user-defined types.


            3. It contains no value and one is assigned:

              Reverting to no value in the face of an exception on constructing is simple enough.


            4. It contains no value and no value is assigned:

              Trivial.


            std::variant has the same easy time when the type stored does not change.

            Unfortunately, when a different type is assigned it must make place for it by destroying the previous value, and then constructing the new value might throw!



            As the previous value is already lost, what can you do?

            Mark it as valueless by exception to have a stable, valid though undesirable state, and let the exception propagate.



            One could use extra space and time to allocate the values dynamically, save the old value somewhere temporarily, construct the new value before assigning or the like, but all those strategies are costly, and only the first always works.






            share|improve this answer































              7















              std::optional has it easy:



              1. It contains a value and a new value is assigned:

                Easy, just delegate to the assignment operator and let it deal with it. Even in the case of an exception, there will still be a value left.


              2. It contains a value and the value is removed:

                Easy, the dtor must not throw. The standard library generally assumes that for user-defined types.


              3. It contains no value and one is assigned:

                Reverting to no value in the face of an exception on constructing is simple enough.


              4. It contains no value and no value is assigned:

                Trivial.


              std::variant has the same easy time when the type stored does not change.

              Unfortunately, when a different type is assigned it must make place for it by destroying the previous value, and then constructing the new value might throw!



              As the previous value is already lost, what can you do?

              Mark it as valueless by exception to have a stable, valid though undesirable state, and let the exception propagate.



              One could use extra space and time to allocate the values dynamically, save the old value somewhere temporarily, construct the new value before assigning or the like, but all those strategies are costly, and only the first always works.






              share|improve this answer





























                7














                7










                7









                std::optional has it easy:



                1. It contains a value and a new value is assigned:

                  Easy, just delegate to the assignment operator and let it deal with it. Even in the case of an exception, there will still be a value left.


                2. It contains a value and the value is removed:

                  Easy, the dtor must not throw. The standard library generally assumes that for user-defined types.


                3. It contains no value and one is assigned:

                  Reverting to no value in the face of an exception on constructing is simple enough.


                4. It contains no value and no value is assigned:

                  Trivial.


                std::variant has the same easy time when the type stored does not change.

                Unfortunately, when a different type is assigned it must make place for it by destroying the previous value, and then constructing the new value might throw!



                As the previous value is already lost, what can you do?

                Mark it as valueless by exception to have a stable, valid though undesirable state, and let the exception propagate.



                One could use extra space and time to allocate the values dynamically, save the old value somewhere temporarily, construct the new value before assigning or the like, but all those strategies are costly, and only the first always works.






                share|improve this answer















                std::optional has it easy:



                1. It contains a value and a new value is assigned:

                  Easy, just delegate to the assignment operator and let it deal with it. Even in the case of an exception, there will still be a value left.


                2. It contains a value and the value is removed:

                  Easy, the dtor must not throw. The standard library generally assumes that for user-defined types.


                3. It contains no value and one is assigned:

                  Reverting to no value in the face of an exception on constructing is simple enough.


                4. It contains no value and no value is assigned:

                  Trivial.


                std::variant has the same easy time when the type stored does not change.

                Unfortunately, when a different type is assigned it must make place for it by destroying the previous value, and then constructing the new value might throw!



                As the previous value is already lost, what can you do?

                Mark it as valueless by exception to have a stable, valid though undesirable state, and let the exception propagate.



                One could use extra space and time to allocate the values dynamically, save the old value somewhere temporarily, construct the new value before assigning or the like, but all those strategies are costly, and only the first always works.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited 7 hours ago

























                answered 8 hours ago









                DeduplicatorDeduplicator

                37.4k6 gold badges52 silver badges91 bronze badges




                37.4k6 gold badges52 silver badges91 bronze badges
























                    4















                    "valueless by exception" refers to a specific scenario where you need to change the type stored in the variant. That necessarily requires 1) destroying the old value and then 2) creating the new one in its place. If 2) fails, you have no way to go back (without undue overhead unacceptable to the committee).



                    optional doesn't have this problem. If some operation on the object it contains throws an exception, so be it. The object is still there. That doesn't mean that the object's state is still meaningful - it's whatever the throwing operation leaves it in. Hopefully that operation has at least the basic guarantee.






                    share|improve this answer



























                    • "the initialization state of *this is unchanged" ... am I misunderstanding that statement? I think you're saying that it could change to something not meaningful.

                      – Drew Dormann
                      8 hours ago






                    • 1





                      From optional's perspective, it's still holding an object. Whether that object is in a usable state is not optional's concern.

                      – T.C.
                      8 hours ago











                    • It is quite an important detail that std::optional::operator= uses T::operator= instead of destroying + constructing the T value. emplace does the latter (and leaves the optional empty if construction of the new value throws).

                      – Max Langhof
                      8 hours ago
















                    4















                    "valueless by exception" refers to a specific scenario where you need to change the type stored in the variant. That necessarily requires 1) destroying the old value and then 2) creating the new one in its place. If 2) fails, you have no way to go back (without undue overhead unacceptable to the committee).



                    optional doesn't have this problem. If some operation on the object it contains throws an exception, so be it. The object is still there. That doesn't mean that the object's state is still meaningful - it's whatever the throwing operation leaves it in. Hopefully that operation has at least the basic guarantee.






                    share|improve this answer



























                    • "the initialization state of *this is unchanged" ... am I misunderstanding that statement? I think you're saying that it could change to something not meaningful.

                      – Drew Dormann
                      8 hours ago






                    • 1





                      From optional's perspective, it's still holding an object. Whether that object is in a usable state is not optional's concern.

                      – T.C.
                      8 hours ago











                    • It is quite an important detail that std::optional::operator= uses T::operator= instead of destroying + constructing the T value. emplace does the latter (and leaves the optional empty if construction of the new value throws).

                      – Max Langhof
                      8 hours ago














                    4














                    4










                    4









                    "valueless by exception" refers to a specific scenario where you need to change the type stored in the variant. That necessarily requires 1) destroying the old value and then 2) creating the new one in its place. If 2) fails, you have no way to go back (without undue overhead unacceptable to the committee).



                    optional doesn't have this problem. If some operation on the object it contains throws an exception, so be it. The object is still there. That doesn't mean that the object's state is still meaningful - it's whatever the throwing operation leaves it in. Hopefully that operation has at least the basic guarantee.






                    share|improve this answer















                    "valueless by exception" refers to a specific scenario where you need to change the type stored in the variant. That necessarily requires 1) destroying the old value and then 2) creating the new one in its place. If 2) fails, you have no way to go back (without undue overhead unacceptable to the committee).



                    optional doesn't have this problem. If some operation on the object it contains throws an exception, so be it. The object is still there. That doesn't mean that the object's state is still meaningful - it's whatever the throwing operation leaves it in. Hopefully that operation has at least the basic guarantee.







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited 8 hours ago

























                    answered 8 hours ago









                    T.C.T.C.

                    111k14 gold badges228 silver badges337 bronze badges




                    111k14 gold badges228 silver badges337 bronze badges















                    • "the initialization state of *this is unchanged" ... am I misunderstanding that statement? I think you're saying that it could change to something not meaningful.

                      – Drew Dormann
                      8 hours ago






                    • 1





                      From optional's perspective, it's still holding an object. Whether that object is in a usable state is not optional's concern.

                      – T.C.
                      8 hours ago











                    • It is quite an important detail that std::optional::operator= uses T::operator= instead of destroying + constructing the T value. emplace does the latter (and leaves the optional empty if construction of the new value throws).

                      – Max Langhof
                      8 hours ago


















                    • "the initialization state of *this is unchanged" ... am I misunderstanding that statement? I think you're saying that it could change to something not meaningful.

                      – Drew Dormann
                      8 hours ago






                    • 1





                      From optional's perspective, it's still holding an object. Whether that object is in a usable state is not optional's concern.

                      – T.C.
                      8 hours ago











                    • It is quite an important detail that std::optional::operator= uses T::operator= instead of destroying + constructing the T value. emplace does the latter (and leaves the optional empty if construction of the new value throws).

                      – Max Langhof
                      8 hours ago

















                    "the initialization state of *this is unchanged" ... am I misunderstanding that statement? I think you're saying that it could change to something not meaningful.

                    – Drew Dormann
                    8 hours ago





                    "the initialization state of *this is unchanged" ... am I misunderstanding that statement? I think you're saying that it could change to something not meaningful.

                    – Drew Dormann
                    8 hours ago




                    1




                    1





                    From optional's perspective, it's still holding an object. Whether that object is in a usable state is not optional's concern.

                    – T.C.
                    8 hours ago





                    From optional's perspective, it's still holding an object. Whether that object is in a usable state is not optional's concern.

                    – T.C.
                    8 hours ago













                    It is quite an important detail that std::optional::operator= uses T::operator= instead of destroying + constructing the T value. emplace does the latter (and leaves the optional empty if construction of the new value throws).

                    – Max Langhof
                    8 hours ago






                    It is quite an important detail that std::optional::operator= uses T::operator= instead of destroying + constructing the T value. emplace does the latter (and leaves the optional empty if construction of the new value throws).

                    – Max Langhof
                    8 hours ago


















                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f57696187%2fhow-is-stdoptional-never-valueless-by-exception%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Invision Community Contents History See also References External links Navigation menuProprietaryinvisioncommunity.comIPS Community ForumsIPS Community Forumsthis blog entry"License Changes, IP.Board 3.4, and the Future""Interview -- Matt Mecham of Ibforums""CEO Invision Power Board, Matt Mecham Is a Liar, Thief!"IPB License Explanation 1.3, 1.3.1, 2.0, and 2.1ArchivedSecurity Fixes, Updates And Enhancements For IPB 1.3.1Archived"New Demo Accounts - Invision Power Services"the original"New Default Skin"the original"Invision Power Board 3.0.0 and Applications Released"the original"Archived copy"the original"Perpetual licenses being done away with""Release Notes - Invision Power Services""Introducing: IPS Community Suite 4!"Invision Community Release Notes

                    Canceling a color specificationRandomly assigning color to Graphics3D objects?Default color for Filling in Mathematica 9Coloring specific elements of sets with a prime modified order in an array plotHow to pick a color differing significantly from the colors already in a given color list?Detection of the text colorColor numbers based on their valueCan color schemes for use with ColorData include opacity specification?My dynamic color schemes

                    Ласкавець круглолистий Зміст Опис | Поширення | Галерея | Примітки | Посилання | Навігаційне меню58171138361-22960890446Bupleurum rotundifoliumEuro+Med PlantbasePlants of the World Online — Kew ScienceGermplasm Resources Information Network (GRIN)Ласкавецькн. VI : Літери Ком — Левиправивши або дописавши її