Why does std::optional::operator=(U&&) require U to be a non-scalar type?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
7
down vote

favorite












For optional's template<class U = T> optional<T>& operator=(U&& v); the standard demands that (see [optional.assign]/3.16):




This function shall not participate in overload resolution unless
...
conjunction_v<is_scalar<T>, is_same<T, decay_t<U>>> is false
...




Why do we have to exclude case when assigning a scalar of type U == T?










share|improve this question



















  • 3




    probably because then another overload is fine. Looking at a single overload doesnt really give you the full picture
    – user463035818
    4 hours ago










  • Types are all special cases..., but fundamental types and void in particular are very boring!
    – Oliv
    3 mins ago














up vote
7
down vote

favorite












For optional's template<class U = T> optional<T>& operator=(U&& v); the standard demands that (see [optional.assign]/3.16):




This function shall not participate in overload resolution unless
...
conjunction_v<is_scalar<T>, is_same<T, decay_t<U>>> is false
...




Why do we have to exclude case when assigning a scalar of type U == T?










share|improve this question



















  • 3




    probably because then another overload is fine. Looking at a single overload doesnt really give you the full picture
    – user463035818
    4 hours ago










  • Types are all special cases..., but fundamental types and void in particular are very boring!
    – Oliv
    3 mins ago












up vote
7
down vote

favorite









up vote
7
down vote

favorite











For optional's template<class U = T> optional<T>& operator=(U&& v); the standard demands that (see [optional.assign]/3.16):




This function shall not participate in overload resolution unless
...
conjunction_v<is_scalar<T>, is_same<T, decay_t<U>>> is false
...




Why do we have to exclude case when assigning a scalar of type U == T?










share|improve this question















For optional's template<class U = T> optional<T>& operator=(U&& v); the standard demands that (see [optional.assign]/3.16):




This function shall not participate in overload resolution unless
...
conjunction_v<is_scalar<T>, is_same<T, decay_t<U>>> is false
...




Why do we have to exclude case when assigning a scalar of type U == T?







c++ language-lawyer c++17 optional






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 3 hours ago









Barry

172k18296540




172k18296540










asked 4 hours ago









Zelta

305211




305211







  • 3




    probably because then another overload is fine. Looking at a single overload doesnt really give you the full picture
    – user463035818
    4 hours ago










  • Types are all special cases..., but fundamental types and void in particular are very boring!
    – Oliv
    3 mins ago












  • 3




    probably because then another overload is fine. Looking at a single overload doesnt really give you the full picture
    – user463035818
    4 hours ago










  • Types are all special cases..., but fundamental types and void in particular are very boring!
    – Oliv
    3 mins ago







3




3




probably because then another overload is fine. Looking at a single overload doesnt really give you the full picture
– user463035818
4 hours ago




probably because then another overload is fine. Looking at a single overload doesnt really give you the full picture
– user463035818
4 hours ago












Types are all special cases..., but fundamental types and void in particular are very boring!
– Oliv
3 mins ago




Types are all special cases..., but fundamental types and void in particular are very boring!
– Oliv
3 mins ago












1 Answer
1






active

oldest

votes

















up vote
12
down vote



accepted










This exists to support:



optional<int> o(42);
o = ; // <== we want this to reset o


We have a bunch of assignment overloads, which take:



  1. nullopt_t

  2. optional const&

  3. optional&&

  4. U&&

  5. optional<U> const&

  6. optional<U>&&

For scalars, specifically, #4 would be a standard conversion whereas anything else would be a user-defined conversion - so it would be the best match. However, the result of that would be assigning o to be engaged with a value of 0. That would mean that o = could potentially mean different things depending on the type of T. Hence, we exclude scalars.



For non-scalars, #4 and #3 would be equivalent (both user-defined conversions), and #3 would win by being a non-template. No problem there.






share|improve this answer




















    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',
    convertImagesToLinks: true,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    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%2f53052395%2fwhy-does-stdoptionaloperator-u-require-u-to-be-a-non-scalar-type%23new-answer', 'question_page');

    );

    Post as a guest






























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    12
    down vote



    accepted










    This exists to support:



    optional<int> o(42);
    o = ; // <== we want this to reset o


    We have a bunch of assignment overloads, which take:



    1. nullopt_t

    2. optional const&

    3. optional&&

    4. U&&

    5. optional<U> const&

    6. optional<U>&&

    For scalars, specifically, #4 would be a standard conversion whereas anything else would be a user-defined conversion - so it would be the best match. However, the result of that would be assigning o to be engaged with a value of 0. That would mean that o = could potentially mean different things depending on the type of T. Hence, we exclude scalars.



    For non-scalars, #4 and #3 would be equivalent (both user-defined conversions), and #3 would win by being a non-template. No problem there.






    share|improve this answer
























      up vote
      12
      down vote



      accepted










      This exists to support:



      optional<int> o(42);
      o = ; // <== we want this to reset o


      We have a bunch of assignment overloads, which take:



      1. nullopt_t

      2. optional const&

      3. optional&&

      4. U&&

      5. optional<U> const&

      6. optional<U>&&

      For scalars, specifically, #4 would be a standard conversion whereas anything else would be a user-defined conversion - so it would be the best match. However, the result of that would be assigning o to be engaged with a value of 0. That would mean that o = could potentially mean different things depending on the type of T. Hence, we exclude scalars.



      For non-scalars, #4 and #3 would be equivalent (both user-defined conversions), and #3 would win by being a non-template. No problem there.






      share|improve this answer






















        up vote
        12
        down vote



        accepted







        up vote
        12
        down vote



        accepted






        This exists to support:



        optional<int> o(42);
        o = ; // <== we want this to reset o


        We have a bunch of assignment overloads, which take:



        1. nullopt_t

        2. optional const&

        3. optional&&

        4. U&&

        5. optional<U> const&

        6. optional<U>&&

        For scalars, specifically, #4 would be a standard conversion whereas anything else would be a user-defined conversion - so it would be the best match. However, the result of that would be assigning o to be engaged with a value of 0. That would mean that o = could potentially mean different things depending on the type of T. Hence, we exclude scalars.



        For non-scalars, #4 and #3 would be equivalent (both user-defined conversions), and #3 would win by being a non-template. No problem there.






        share|improve this answer












        This exists to support:



        optional<int> o(42);
        o = ; // <== we want this to reset o


        We have a bunch of assignment overloads, which take:



        1. nullopt_t

        2. optional const&

        3. optional&&

        4. U&&

        5. optional<U> const&

        6. optional<U>&&

        For scalars, specifically, #4 would be a standard conversion whereas anything else would be a user-defined conversion - so it would be the best match. However, the result of that would be assigning o to be engaged with a value of 0. That would mean that o = could potentially mean different things depending on the type of T. Hence, we exclude scalars.



        For non-scalars, #4 and #3 would be equivalent (both user-defined conversions), and #3 would win by being a non-template. No problem there.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 3 hours ago









        Barry

        172k18296540




        172k18296540



























             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53052395%2fwhy-does-stdoptionaloperator-u-require-u-to-be-a-non-scalar-type%23new-answer', 'question_page');

            );

            Post as a guest













































































            Popular posts from this blog

            How to check contact read email or not when send email to Individual?

            Christian Cage

            How to properly install USB display driver for Fresco Logic FL2000DX on Ubuntu?