Why does std::optional::operator=(U&&) require U to be a non-scalar type?
Clash 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>>>
isfalse
...
Why do we have to exclude case when assigning a scalar of type U == T
?
c++ language-lawyer c++17 optional
add a comment |Â
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>>>
isfalse
...
Why do we have to exclude case when assigning a scalar of type U == T
?
c++ language-lawyer c++17 optional
3
probably because then another overload is fine. Looking at a single overload doesnt really give you the full picture
â user463035818
4 hours ago
add a comment |Â
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>>>
isfalse
...
Why do we have to exclude case when assigning a scalar of type U == T
?
c++ language-lawyer c++17 optional
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>>>
isfalse
...
Why do we have to exclude case when assigning a scalar of type U == T
?
c++ language-lawyer c++17 optional
c++ language-lawyer c++17 optional
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
add a comment |Â
3
probably because then another overload is fine. Looking at a single overload doesnt really give you the full picture
â user463035818
4 hours 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
add a comment |Â
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:
nullopt_t
optional const&
optional&&
U&&
optional<U> const&
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.
add a comment |Â
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:
nullopt_t
optional const&
optional&&
U&&
optional<U> const&
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.
add a comment |Â
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:
nullopt_t
optional const&
optional&&
U&&
optional<U> const&
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.
add a comment |Â
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:
nullopt_t
optional const&
optional&&
U&&
optional<U> const&
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.
This exists to support:
optional<int> o(42);
o = ; // <== we want this to reset o
We have a bunch of assignment overloads, which take:
nullopt_t
optional const&
optional&&
U&&
optional<U> const&
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.
answered 3 hours ago
Barry
172k18296540
172k18296540
add a comment |Â
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%2f53052395%2fwhy-does-stdoptionaloperator-u-require-u-to-be-a-non-scalar-type%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
3
probably because then another overload is fine. Looking at a single overload doesnt really give you the full picture
â user463035818
4 hours ago