Use more C++17 features

Mainly structured bindings, inline variables, and class template
argument deduction, plus many more smaller things.

Change-Id: I810d17e0adb470426e4e30c898e03b3140ad052f
diff --git a/tools/nfdc/command-definition.hpp b/tools/nfdc/command-definition.hpp
index dc5afed..8cd56d9 100644
--- a/tools/nfdc/command-definition.hpp
+++ b/tools/nfdc/command-definition.hpp
@@ -122,7 +122,8 @@
   YES = true  ///< argument can be specified as positional
 };
 
-/** \brief declares semantics of a command
+/**
+ * \brief Defines a command
  */
 class CommandDefinition
 {
@@ -133,17 +134,17 @@
     using std::invalid_argument::invalid_argument;
   };
 
-  CommandDefinition(const std::string& noun, const std::string& verb);
+  CommandDefinition(std::string_view noun, std::string_view verb);
 
   ~CommandDefinition();
 
-  const std::string
+  const std::string&
   getNoun() const
   {
     return m_noun;
   }
 
-  const std::string
+  const std::string&
   getVerb() const
   {
     return m_verb;
@@ -162,7 +163,7 @@
    *  \param title one-line description, written in lower case
    */
   CommandDefinition&
-  setTitle(const std::string& title)
+  setTitle(std::string_view title)
   {
     m_title = title;
     return *this;
@@ -191,12 +192,12 @@
   parse(const std::vector<std::string>& tokens, size_t start = 0) const;
 
 private:
-  std::any
-  parseValue(ArgValueType valueType, const std::string& token) const;
+  static std::any
+  parseValue(ArgValueType valueType, const std::string& token);
 
 private:
-  std::string m_noun;
-  std::string m_verb;
+  const std::string m_noun;
+  const std::string m_verb;
   std::string m_title;
 
   struct Arg