Move constructors should always be marked noexcept, otherwise the object
cannot be placed into most standard library containers (as they
generally use std::move_if_noexcept to enforce strong exception
guarantees), and if this is false, then the container will fallback to
attempting to copy construct the object. Naturally, this cannot occur
without compilation errors for objects that have their copy constructor
and copy-assignment operators deleted (like Socket).
While we're at it, we can make most of the socket interface noexcept,
given they just forward to the POSIX socket functions.
Prevents various error-prone cases of implicit conversion to bool, while
retaining general conversions within conditional statements. We also
disable implicit conversions with constructors that may be ambiguous to
enforce being clear with intentions.