0

Can either of the following template methods be declared noexcept?

template <typename T>
std::optional<T> foo(const T& value) // noexcept?
{
    try {
        // code possibly returning a T or a std::nullopt
    } catch(...) {
        return std::nullopt;
    }
}

template <typename T>
boost::optional<T> bar(const T& value) // noexcept?
{
    try {
        // code possibly returning a T or a boost::none
    } catch(...) {
        return boost::none;
    }
}

In other words, can an uninitialised std/boost::optional (nullopt/none) throw?

Daniel
  • 8,179
  • 6
  • 31
  • 56
  • 1
    Not sure if I follow the question. An unitialized optional will throw if you attempt to extract it's value through `value()`. – SergeyA Jan 14 '16 at 20:59
  • Sure, but can the *construction* of an uninitialised optional throw (i.e. can the functions in the question be declared `noexcept`)? – Daniel Jan 14 '16 at 21:01
  • 1
    Default constructor of `optional` is `noexcept`. Is this your question? – SergeyA Jan 14 '16 at 21:04
  • Yes... that would be a nicer way of putting it! Do you have references? – Daniel Jan 14 '16 at 21:07
  • with a `try-catch` block that doesn't rethrow, you can declare the functions `noexcept` anyway, right? http://stackoverflow.com/a/28975065/27678 – AndyG Jan 14 '16 at 21:15

2 Answers2

1

Default constructor of optional is declared noexcept, as per http://en.cppreference.com/w/cpp/experimental/optional/optional.

SergeyA
  • 61,605
  • 5
  • 78
  • 137
0

You're constructing an optional<T> from a value of T (probably a T&&), which in turn calls the corresponding ctor of T. If T's ctor throws, then so does optional's ctor. Depending upon what the missing code inside the try{} block does, your exception specification should be something like

noexcept(std::is_nothrow_move_constructible<T>::value)

or

noexcept(std::is_nothrow_constructible<T>::value)
John
  • 131
  • 1
  • 2