Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 273
Zelta Avatar asked Oct 29 '18 19:10

Zelta


People also ask

What is std :: optional for?

The class template std::optional manages an optional contained value, i.e. a value that may or may not be present. A common use case for optional is the return value of a function that may fail.

Does STD optional allocate?

What's more, std::optional doesn't need to allocate any memory on the free store. std::optional is a part of C++ vocabulary types along with std::any , std::variant and std::string_view .

Is std :: Optional A Monad?

Abstract. std::optional is an important vocabulary type in C++17. Some uses of it are verbose and would benefit from operations which allow functional composition. I propose adding transform, and_then, and or_else member functions to std::optional to support this monadic style of programming.

What is Nullopt in C++?

C++17 introduced std::optional<T> which lets you augment the values of a type T with a bonus value known as std::nullopt which semantically represents the absence of a value. A std::optional which holds the value std::nullopt is known as empty.


1 Answers

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.

like image 156
Barry Avatar answered Nov 15 '22 22:11

Barry