23 General utilities library [utilities]

23.8 Storage for any type [any]

23.8.3 Class any [any.class]

class any {
public:
  // [any.cons], construction and destruction
  constexpr any() noexcept;

  any(const any& other);
  any(any&& other) noexcept;

  template <class T> any(T&& value);

  template <class T, class... Args>
    explicit any(in_place_type_t<T>, Args&&...);
  template <class T, class U, class... Args>
    explicit any(in_place_type_t<T>, initializer_list<U>, Args&&...);

  ~any();

  // [any.assign], assignments
  any& operator=(const any& rhs);
  any& operator=(any&& rhs) noexcept;

  template <class T> any& operator=(T&& rhs);

  // [any.modifiers], modifiers
  template <class T, class... Args>
    decay_t<T>& emplace(Args&& ...);
  template <class T, class U, class... Args>
    decay_t<T>& emplace(initializer_list<U>, Args&&...);
  void reset() noexcept;
  void swap(any& rhs) noexcept;

  // [any.observers], observers
  bool has_value() const noexcept;
  const type_info& type() const noexcept;
};

An object of class any stores an instance of any type that satisfies the constructor requirements or it has no value, and this is referred to as the state of the class any object. The stored instance is called the contained value, Two states are equivalent if either they both have no value, or both have a value and the contained values are equivalent.

The non-member any_­cast functions provide type-safe access to the contained value.

Implementations should avoid the use of dynamically allocated memory for a small contained value. [Example: where the object constructed is holding only an int. end example] Such small-object optimization shall only be applied to types T for which is_­nothrow_­move_­constructible_­v<T> is true.

23.8.3.1 Construction and destruction [any.cons]

constexpr any() noexcept;

Postconditions: has_­value() is false.

any(const any& other);

Effects: If other.has_­value() is false, constructs an object that has no value. Otherwise, equivalent to any(in_­place<T>, any_­cast<const T&>(other)) where T is the type of the contained object.

Throws: Any exceptions arising from calling the selected constructor for the contained value.

any(any&& other) noexcept;

Effects: If other.has_­value() is false, constructs an object that has no value. Otherwise, constructs an object of type any that contains either the contained object of other, or contains an object of the same type constructed from the contained object of other considering that contained object as an rvalue.

Postconditions: other is left in a valid but otherwise unspecified state.

template<class T> any(T&& value);

Let VT be decay_­t<T>.

Requires: VT shall satisfy the CopyConstructible requirements.

Effects: Constructs an object of type any that contains an object of type VT direct-initialized with std​::​forward<T>(value).

Remarks: This constructor shall not participate in overload resolution unless VT is not the same type as any, VT is not a specialization of in_­place_­type_­t, and is_­copy_­constructible_­v<VT> is true.

Throws: Any exception thrown by the selected constructor of VT.

template <class T, class... Args> explicit any(in_place_type_t<T>, Args&&... args);

Let VT be decay_­t<T>.

Requires: VT shall satisfy the CopyConstructible requirements.

Effects: Initializes the contained value as if direct-non-list-initializing an object of type VT with the arguments std​::​forward<Args>(args)....

Postconditions: *this contains a value of type VT.

Throws: Any exception thrown by the selected constructor of VT.

Remarks: This constructor shall not participate in overload resolution unless is_­copy_­constructible_­v<VT> is true and is_­constructible_­v<VT, Args...> is true.

template <class T, class U, class... Args> explicit any(in_place_type_t<T>, initializer_list<U> il, Args&&... args);

Let VT be decay_­t<T>.

Requires: VT shall satisfy the CopyConstructible requirements.

Effects: Initializes the contained value as if direct-non-list-initializing an object of type VT with the arguments il, std​::​forward<Args>(args)....

Postconditions: *this contains a value.

Throws: Any exception thrown by the selected constructor of VT.

Remarks: This constructor shall not participate in overload resolution unless is_­copy_­constructible_­v<VT> is true and is_­constructible_­v<VT, initializer_­list<U>&, Args...> is true.

~any();

Effects: As if by reset().

23.8.3.2 Assignment [any.assign]

any& operator=(const any& rhs);

Effects: As if by any(rhs).swap(*this). No effects if an exception is thrown.

Returns: *this.

Throws: Any exceptions arising from the copy constructor for the contained value.

any& operator=(any&& rhs) noexcept;

Effects: As if by any(std​::​move(rhs)).swap(*this).

Returns: *this.

Postconditions: The state of *this is equivalent to the original state of rhs and rhs is left in a valid but otherwise unspecified state.

template<class T> any& operator=(T&& rhs);

Let VT be decay_­t<T>.

Requires: VT shall satisfy the CopyConstructible requirements.

Effects: Constructs an object tmp of type any that contains an object of type VT direct-initialized with std​::​forward<T>(rhs), and tmp.swap(*this). No effects if an exception is thrown.

Returns: *this.

Remarks: This operator shall not participate in overload resolution unless VT is not the same type as any and is_­copy_­constructible_­v<VT> is true.

Throws: Any exception thrown by the selected constructor of VT.

23.8.3.3 Modifiers [any.modifiers]

template <class T, class... Args> decay_t<T>& emplace(Args&&... args);

Let VT be decay_­t<T>.

Requires: VT shall satisfy the CopyConstructible requirements.

Effects: Calls reset(). Then initializes the contained value as if direct-non-list-initializing an object of type VT with the arguments std​::​forward<Args>(args)....

Postconditions: *this contains a value.

Returns: A reference to the new contained value.

Throws: Any exception thrown by the selected constructor of VT.

Remarks: If an exception is thrown during the call to VT's constructor, *this does not contain a value, and any previously contained value has been destroyed. This function shall not participate in overload resolution unless is_­copy_­constructible_­v<VT> is true and is_­constructible_­v<VT, Args...> is true.

template <class T, class U, class... Args> decay_t<T>& emplace(initializer_list<U> il, Args&&... args);

Let VT be decay_­t<T>.

Requires: VT shall satisfy the CopyConstructible requirements.

Effects: Calls reset(). Then initializes the contained value as if direct-non-list-initializing an object of type VT with the arguments il, std​::​forward<Args>(args)....

Postconditions: *this contains a value.

Returns: A reference to the new contained value.

Throws: Any exception thrown by the selected constructor of VT.

Remarks: If an exception is thrown during the call to VT's constructor, *this does not contain a value, and any previously contained value has been destroyed. The function shall not participate in overload resolution unless is_­copy_­constructible_­v<VT> is true and is_­constructible_­v<VT, initializer_­list<U>&, Args...> is true.

void reset() noexcept;

Effects: If has_­value() is true, destroys the contained value.

Postconditions: has_­value() is false.

void swap(any& rhs) noexcept;

Effects: Exchanges the states of *this and rhs.

23.8.3.4 Observers [any.observers]

bool has_value() const noexcept;

Returns: true if *this contains an object, otherwise false.

const type_info& type() const noexcept;

Returns: typeid(T) if *this has a contained value of type T, otherwise typeid(void).

[Note: Useful for querying against types known either at compile time or only at runtime. end note]