fd: Add an empty default constructor

We sometimes want to be able to construct a placeholder fd even though
it isn't populated yet.

Change-Id: I5115dfb46be6d2e67ff0ed629842ab97fda9c0e2
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/stdplus/fd/dupable.cpp b/src/stdplus/fd/dupable.cpp
index 96e347f..ce2cff1 100644
--- a/src/stdplus/fd/dupable.cpp
+++ b/src/stdplus/fd/dupable.cpp
@@ -18,6 +18,10 @@
 
 } // namespace detail
 
+DupableFd::DupableFd() noexcept : handle(std::nullopt)
+{
+}
+
 DupableFd::DupableFd(const int& fd) : handle(fd)
 {
 }
diff --git a/src/stdplus/fd/dupable.hpp b/src/stdplus/fd/dupable.hpp
index b008ce0..0f810cf 100644
--- a/src/stdplus/fd/dupable.hpp
+++ b/src/stdplus/fd/dupable.hpp
@@ -23,6 +23,9 @@
 class DupableFd : public FdImpl
 {
   public:
+    /** @brief Constructs an empty file descriptor */
+    DupableFd() noexcept;
+
     /** @brief Duplicates and holds a file descriptor
      *         Does not automatically close the input descriptor
      *
diff --git a/src/stdplus/fd/managed.cpp b/src/stdplus/fd/managed.cpp
index 4611143..1b19284 100644
--- a/src/stdplus/fd/managed.cpp
+++ b/src/stdplus/fd/managed.cpp
@@ -20,6 +20,10 @@
 
 } // namespace detail
 
+ManagedFd::ManagedFd() noexcept : handle(std::nullopt)
+{
+}
+
 ManagedFd::ManagedFd(int&& fd) : handle(std::move(fd))
 {
     fd::setFdFlags(*this, fd::getFdFlags(*this).set(fd::FdFlag::CloseOnExec));
diff --git a/src/stdplus/fd/managed.hpp b/src/stdplus/fd/managed.hpp
index 3b9dde3..a188421 100644
--- a/src/stdplus/fd/managed.hpp
+++ b/src/stdplus/fd/managed.hpp
@@ -28,6 +28,9 @@
 class ManagedFd : public FdImpl
 {
   public:
+    /** @brief Constructs an empty file descriptor */
+    ManagedFd() noexcept;
+
     /** @brief Holds the input file descriptor
      *         Becomes the sole owner of the file descriptor
      *