face: reimplement EndpointId with std::variant

Refs: #5041
Change-Id: Ib8aced49a7aa14b137fb06de4a0ae8b979f07587
diff --git a/daemon/face/face-endpoint.hpp b/daemon/face/face-endpoint.hpp
index 366c743..c9badef 100644
--- a/daemon/face/face-endpoint.hpp
+++ b/daemon/face/face-endpoint.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2021,  Regents of the University of California,
+ * Copyright (c) 2014-2022,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -30,16 +30,25 @@
 
 namespace nfd {
 
-/** \brief Represents a face-endpoint pair in the forwarder.
- *  \sa face::Face, face::EndpointId
+/**
+ * \brief Represents a face-endpoint pair in the forwarder.
+ * \sa face::Face, face::EndpointId
  */
 class FaceEndpoint
 {
 public:
-  FaceEndpoint(Face& face, EndpointId endpoint)
-    : face(face)
-    , endpoint(endpoint)
+  explicit
+  FaceEndpoint(Face& face, const EndpointId& endpoint = {});
+
+private:
+  void
+  print(std::ostream& os) const;
+
+  friend std::ostream&
+  operator<<(std::ostream& os, const FaceEndpoint& fe)
   {
+    fe.print(os);
+    return os;
   }
 
 public:
@@ -47,12 +56,6 @@
   const EndpointId endpoint;
 };
 
-inline std::ostream&
-operator<<(std::ostream& os, const FaceEndpoint& fe)
-{
-  return os << '(' << fe.face.getId() << ',' << fe.endpoint << ')';
-}
-
 } // namespace nfd
 
 #endif // NFD_DAEMON_FACE_FACE_ENDPOINT_HPP