Search code examples
c++c++17assignment-operatoranynoexcept

Why std::any & operator= for ValueType is not conditionally noexcept?


The question is quite simple.

This is the declaration of templated operator= for std::any:

template<typename ValueType>
any& operator=( ValueType&& rhs );

I would expect it to be:

template<typename ValueType>
any& operator=( ValueType&& rhs ) noexcept(noexcept(std::declval<std::any>() = std::forward<ValueType>(std::declval<ValueType>()));

Namely, if you can copy-assign ValueType to any in a noexcept fashion, then you should be able to have noexcept.

Maybe I am missing something.


Solution

  • The literal answer is that such a specification would be recursive (you're saying the assignment should be noexcept if the assignment is noexcept).

    But the probably more useful answer is that since any may have to allocate, you could only really have noexcept assignment in the case that decay_t<ValueType> is

    • sufficiently small (so as to not need allocation), and
    • nothrow move constructible, and
    • nothrow constructible from ValueType

    The only way to specify the noexcept condition would require you to also specify what "sufficiently small" means - which would limit implementation freedom, for questionable gain.

    The standard library doesn't typically use conditional noexcept - so why would this be the... exception?