diff --git a/hoppy-generator.cabal b/hoppy-generator.cabal
--- a/hoppy-generator.cabal
+++ b/hoppy-generator.cabal
@@ -1,5 +1,5 @@
 name: hoppy-generator
-version: 0.3.2
+version: 0.3.3
 synopsis: C++ FFI generator - Code generator
 homepage: http://khumba.net/projects/hoppy
 license: AGPL-3
diff --git a/src/Foreign/Hoppy/Generator/Language/Cpp/Internal.hs b/src/Foreign/Hoppy/Generator/Language/Cpp/Internal.hs
--- a/src/Foreign/Hoppy/Generator/Language/Cpp/Internal.hs
+++ b/src/Foreign/Hoppy/Generator/Language/Cpp/Internal.hs
@@ -605,8 +605,10 @@
 
       says ["\nclass ", className, " {\n"]
       say "public:\n"
+      says ["    ", className, "() {}\n"]
       says ["    explicit ", className, "(", implClassName, "* impl) : impl_(impl) {}\n"]
       say "    " >> sayVar "operator()" Nothing fnType >> say ";\n"
+      say "    operator bool() const;\n"
       say "private:\n"
       says ["    std::shared_ptr<", implClassName, "> impl_;\n"]
       say "};\n"
@@ -723,6 +725,12 @@
           _ -> say "return (*impl_)("
         sayArgNames paramCount
         say ");\n"
+
+      -- Render "operator bool", which detects whether the callback was not
+      -- default-constructed with no actual impl object.
+      says [className, "::operator bool() const {\n"]
+      say "return static_cast<bool>(impl_);\n"
+      say "}\n"
 
       -- Render the function that creates a new callback object.
       let newCallbackFnType = fnT [ fnPtrCType
diff --git a/src/Foreign/Hoppy/Generator/Main.hs b/src/Foreign/Hoppy/Generator/Main.hs
--- a/src/Foreign/Hoppy/Generator/Main.hs
+++ b/src/Foreign/Hoppy/Generator/Main.hs
@@ -61,6 +61,10 @@
 data Action =
     ListInterfaces
     -- ^ Lists the interfaces compiled into the generator.
+  | ListCppFiles
+    -- ^ Lists the generated files in C++ bindings.
+  | ListHsFiles
+    -- ^ Lists the generated files in Haskell bindings.
   | GenCpp FilePath
     -- ^ Generates C++ wrappers for an interface in the given location.
   | GenHaskell FilePath
@@ -157,6 +161,8 @@
     , "Supported options:"
     , "  --help                      Displays this menu."
     , "  --list-interfaces           Lists the interfaces compiled into this binary."
+    , "  --list-cpp-files            Lists generated file paths in C++ bindings."
+    , "  --list-hs-files             Lists generated file paths in Haskell bindings."
     , "  --gen-cpp <outdir>          Generate C++ bindings in a directory."
     , "  --gen-hs <outdir>           Generate Haskell bindings under the given"
     , "                              top-level source directory."
@@ -170,6 +176,26 @@
     "--list-interfaces":rest -> do
       listInterfaces stateVar
       (ListInterfaces:) <$> processArgs stateVar rest
+
+    "--list-cpp-files":rest -> do
+      genResult <- withCurrentCache stateVar getGeneratedCpp
+      case genResult of
+        Left errorMsg -> do
+          putStrLn $ "--list-cpp-files: Failed to generate: " ++ errorMsg
+          exitFailure
+        Right gen -> do
+          mapM_ putStrLn $ M.keys $ Cpp.generatedFiles gen
+          (ListCppFiles:) <$> processArgs stateVar rest
+
+    "--list-hs-files":rest -> do
+      genResult <- withCurrentCache stateVar getGeneratedHaskell
+      case genResult of
+        Left errorMsg -> do
+          putStrLn $ "--list-hs-files: Failed to generate: " ++ errorMsg
+          exitFailure
+        Right gen -> do
+          mapM_ putStrLn $ M.keys $ Haskell.generatedFiles gen
+          (ListHsFiles:) <$> processArgs stateVar rest
 
     "--gen-cpp":baseDir:rest -> do
       baseDirExists <- doesDirectoryExist baseDir
