common: stop importing std::{bind,ref,cref} into namespace ndn

And reduce the usage of std::bind() throughout the codebase.
C++14 lambdas are easier to understand for humans and more
likely to be optimized by the compiler.

Change-Id: Ia59fad34539710f8801c52914896ce426fb7e538
diff --git a/examples/consumer-with-timer.cpp b/examples/consumer-with-timer.cpp
index b3b35ee..2f9c4d4 100644
--- a/examples/consumer-with-timer.cpp
+++ b/examples/consumer-with-timer.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2019 Regents of the University of California.
+ * Copyright (c) 2013-2021 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -54,9 +54,9 @@
 
     std::cout << "Sending Interest " << interest << std::endl;
     m_face.expressInterest(interest,
-                           bind(&ConsumerWithTimer::onData, this, _1, _2),
-                           bind(&ConsumerWithTimer::onNack, this, _1, _2),
-                           bind(&ConsumerWithTimer::onTimeout, this, _1));
+                           std::bind(&ConsumerWithTimer::onData, this, _1, _2),
+                           std::bind(&ConsumerWithTimer::onNack, this, _1, _2),
+                           std::bind(&ConsumerWithTimer::onTimeout, this, _1));
 
     // Schedule a new event
     m_scheduler.schedule(3_s, [this] { delayedInterest(); });
@@ -104,9 +104,9 @@
 
     std::cout << "Sending Interest " << interest << std::endl;
     m_face.expressInterest(interest,
-                           bind(&ConsumerWithTimer::onData, this, _1, _2),
-                           bind(&ConsumerWithTimer::onNack, this, _1, _2),
-                           bind(&ConsumerWithTimer::onTimeout, this, _1));
+                           std::bind(&ConsumerWithTimer::onData, this, _1, _2),
+                           std::bind(&ConsumerWithTimer::onNack, this, _1, _2),
+                           std::bind(&ConsumerWithTimer::onTimeout, this, _1));
   }
 
 private:
diff --git a/examples/consumer.cpp b/examples/consumer.cpp
index ef6cd76..5808c99 100644
--- a/examples/consumer.cpp
+++ b/examples/consumer.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2019 Regents of the University of California.
+ * Copyright (c) 2013-2021 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -46,9 +46,9 @@
 
     std::cout << "Sending Interest " << interest << std::endl;
     m_face.expressInterest(interest,
-                           bind(&Consumer::onData, this,  _1, _2),
-                           bind(&Consumer::onNack, this, _1, _2),
-                           bind(&Consumer::onTimeout, this, _1));
+                           std::bind(&Consumer::onData, this,  _1, _2),
+                           std::bind(&Consumer::onNack, this, _1, _2),
+                           std::bind(&Consumer::onTimeout, this, _1));
 
     // processEvents will block until the requested data is received or a timeout occurs
     m_face.processEvents();
diff --git a/examples/producer.cpp b/examples/producer.cpp
index 516e1c0..d88cc86 100644
--- a/examples/producer.cpp
+++ b/examples/producer.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2019 Regents of the University of California.
+ * Copyright (c) 2013-2021 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -39,9 +39,9 @@
   run()
   {
     m_face.setInterestFilter("/example/testApp",
-                             bind(&Producer::onInterest, this, _1, _2),
+                             std::bind(&Producer::onInterest, this, _1, _2),
                              nullptr, // RegisterPrefixSuccessCallback is optional
-                             bind(&Producer::onRegisterFailed, this, _1, _2));
+                             std::bind(&Producer::onRegisterFailed, this, _1, _2));
     m_face.processEvents();
   }
 
diff --git a/ndn-cxx/detail/common.hpp b/ndn-cxx/detail/common.hpp
index c65fa09..13570c9 100644
--- a/ndn-cxx/detail/common.hpp
+++ b/ndn-cxx/detail/common.hpp
@@ -74,9 +74,6 @@
 using std::const_pointer_cast;
 
 using std::function;
-using std::bind;
-using std::ref;
-using std::cref;
 
 using namespace std::string_literals;
 
diff --git a/ndn-cxx/impl/face-impl.hpp b/ndn-cxx/impl/face-impl.hpp
index d5acc86..70e6028 100644
--- a/ndn-cxx/impl/face-impl.hpp
+++ b/ndn-cxx/impl/face-impl.hpp
@@ -94,8 +94,8 @@
     this->ensureConnected(true);
 
     const Interest& interest2 = *interest;
-    auto& entry = m_pendingInterestTable.put(id, std::move(interest), afterSatisfied, afterNacked,
-                                             afterTimeout, ref(m_scheduler));
+    auto& entry = m_pendingInterestTable.put(id, std::move(interest), afterSatisfied,
+                                             afterNacked, afterTimeout, m_scheduler);
 
     lp::Packet lpPacket;
     addFieldFromTag<lp::NextHopFaceIdField, lp::NextHopFaceIdTag>(lpPacket, interest2);
@@ -206,7 +206,7 @@
   processIncomingInterest(shared_ptr<const Interest> interest)
   {
     const Interest& interest2 = *interest;
-    auto& entry = m_pendingInterestTable.insert(std::move(interest), ref(m_scheduler));
+    auto& entry = m_pendingInterestTable.insert(std::move(interest), m_scheduler);
     dispatchInterest(entry, interest2);
   }
 
diff --git a/ndn-cxx/mgmt/dispatcher.cpp b/ndn-cxx/mgmt/dispatcher.cpp
index ed0e00c..2973abe 100644
--- a/ndn-cxx/mgmt/dispatcher.cpp
+++ b/ndn-cxx/mgmt/dispatcher.cpp
@@ -77,8 +77,11 @@
 
   for (const auto& entry : m_handlers) {
     Name fullPrefix = Name(prefix).append(entry.first);
-    auto filterHdl = m_face.setInterestFilter(fullPrefix, bind(entry.second, prefix, _2));
-    topPrefixEntry.interestFilters.push_back(filterHdl);
+    auto filterHdl = m_face.setInterestFilter(fullPrefix,
+      [=, cb = entry.second] (const auto&, const auto& interest) {
+        cb(prefix, interest);
+      });
+    topPrefixEntry.interestFilters.emplace_back(std::move(filterHdl));
   }
 }
 
@@ -230,13 +233,14 @@
   }
 
   AuthorizationAcceptedCallback accepted =
-    bind(&Dispatcher::processAuthorizedStatusDatasetInterest, this, _1, _2, _3, std::move(handle));
-  AuthorizationRejectedCallback rejected =
-    bind(&Dispatcher::afterAuthorizationRejected, this, _1, _2);
+    std::bind(&Dispatcher::processAuthorizedStatusDatasetInterest, this, _2, _3, std::move(handle));
+  AuthorizationRejectedCallback rejected = [this] (auto&&... args) {
+    afterAuthorizationRejected(std::forward<decltype(args)>(args)...);
+  };
 
   // follow the general path if storage is a miss
-  InterestHandler missContinuation = bind(&Dispatcher::processStatusDatasetInterest, this, _1, _2,
-                                          std::move(authorize), std::move(accepted), std::move(rejected));
+  InterestHandler missContinuation = std::bind(&Dispatcher::processStatusDatasetInterest, this, _1, _2,
+                                               std::move(authorize), std::move(accepted), std::move(rejected));
 
   m_handlers[relPrefix] = [this, miss = std::move(missContinuation)] (auto&&... args) {
     this->queryStorage(std::forward<decltype(args)>(args)..., miss);
@@ -263,14 +267,17 @@
 }
 
 void
-Dispatcher::processAuthorizedStatusDatasetInterest(const std::string& requester,
-                                                   const Name& prefix,
+Dispatcher::processAuthorizedStatusDatasetInterest(const Name& prefix,
                                                    const Interest& interest,
                                                    const StatusDatasetHandler& handler)
 {
   StatusDatasetContext context(interest,
-                               bind(&Dispatcher::sendStatusDatasetSegment, this, _1, _2, _3),
-                               bind(&Dispatcher::sendControlResponse, this, _1, interest, true));
+    [this] (auto&&... args) {
+      sendStatusDatasetSegment(std::forward<decltype(args)>(args)...);
+    },
+    [this, interest] (auto&&... args) {
+      sendControlResponse(std::forward<decltype(args)>(args)..., interest, true);
+    });
   handler(prefix, interest, context);
 }
 
diff --git a/ndn-cxx/mgmt/dispatcher.hpp b/ndn-cxx/mgmt/dispatcher.hpp
index 43ae1d2..a382e65 100644
--- a/ndn-cxx/mgmt/dispatcher.hpp
+++ b/ndn-cxx/mgmt/dispatcher.hpp
@@ -270,24 +270,21 @@
   addNotificationStream(const PartialName& relPrefix);
 
 private:
-  typedef std::function<void(const Name& prefix,
-                             const Interest& interest)> InterestHandler;
+  using InterestHandler = std::function<void(const Name& prefix, const Interest&)>;
 
-  typedef std::function<void(const std::string& requester,
-                             const Name& prefix,
-                             const Interest& interest,
-                             const shared_ptr<ControlParameters>&)> AuthorizationAcceptedCallback;
+  using AuthorizationAcceptedCallback = std::function<void(const std::string& requester,
+                                                           const Name& prefix,
+                                                           const Interest&,
+                                                           const shared_ptr<ControlParameters>&)>;
 
-  typedef std::function<void(RejectReply act,
-                             const Interest& interest)> AuthorizationRejectedCallback;
+  using AuthorizationRejectedCallback = std::function<void(RejectReply, const Interest&)>;
 
   /**
-   * @brief the parser of extracting control parameters from name component.
-   * @param comp name component that may encode control parameters.
-   * @return a shared pointer to the extracted control parameters.
-   * @throw tlv::Error if the NameComponent cannot be parsed as ControlParameters
+   * @brief the parser for extracting control parameters from a name component.
+   * @return a shared pointer to the extracted ControlParameters.
+   * @throw tlv::Error if the name component cannot be parsed as ControlParameters
    */
-  typedef std::function<shared_ptr<ControlParameters>(const name::Component& comp)> ControlParametersParser;
+  using ControlParametersParser = std::function<shared_ptr<ControlParameters>(const name::Component&)>;
 
   bool
   isOverlappedWithOthers(const PartialName& relPrefix) const;
@@ -404,16 +401,14 @@
                                const AuthorizationRejectedCallback& rejected);
 
   /**
-   * @brief process the authorized status-dataset request
+   * @brief process the authorized StatusDataset request
    *
-   * @param requester the requester
    * @param prefix the top-level prefix
    * @param interest the incoming Interest
-   * @param handler to process this request
+   * @param handler function to process this request
    */
   void
-  processAuthorizedStatusDatasetInterest(const std::string& requester,
-                                         const Name& prefix,
+  processAuthorizedStatusDatasetInterest(const Name& prefix,
                                          const Interest& interest,
                                          const StatusDatasetHandler& handler);
 
@@ -466,20 +461,24 @@
     NDN_THROW(std::out_of_range("relPrefix overlaps with another relPrefix"));
   }
 
-  auto parser = [] (const name::Component& comp) -> shared_ptr<ControlParameters> {
+  ControlParametersParser parser = [] (const name::Component& comp) -> shared_ptr<ControlParameters> {
     return make_shared<CP>(comp.blockFromValue());
   };
+  AuthorizationAcceptedCallback accepted = [this, validate = std::move(validate),
+                                            handle = std::move(handle)] (auto&&... args) {
+    processAuthorizedControlCommandInterest(std::forward<decltype(args)>(args)..., validate, handle);
+  };
+  AuthorizationRejectedCallback rejected = [this] (auto&&... args) {
+    afterAuthorizationRejected(std::forward<decltype(args)>(args)...);
+  };
 
-  AuthorizationAcceptedCallback accepted =
-    bind(&Dispatcher::processAuthorizedControlCommandInterest, this,
-         _1, _2, _3, _4, std::move(validate), std::move(handle));
-
-  AuthorizationRejectedCallback rejected =
-    bind(&Dispatcher::afterAuthorizationRejected, this, _1, _2);
-
-  m_handlers[relPrefix] = bind(&Dispatcher::processControlCommandInterest, this,
-                               _1, relPrefix, _2, std::move(parser), std::move(authorize),
-                               std::move(accepted), std::move(rejected));
+  m_handlers[relPrefix] = [this, relPrefix,
+                           parser = std::move(parser),
+                           authorize = std::move(authorize),
+                           accepted = std::move(accepted),
+                           rejected = std::move(rejected)] (const auto& prefix, const auto& interest) {
+    processControlCommandInterest(prefix, relPrefix, interest, parser, authorize, accepted, rejected);
+  };
 }
 
 } // namespace mgmt
diff --git a/ndn-cxx/net/dns.cpp b/ndn-cxx/net/dns.cpp
index c3e04b1..9b0a9f1 100644
--- a/ndn-cxx/net/dns.cpp
+++ b/ndn-cxx/net/dns.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2019 Regents of the University of California.
+ * Copyright (c) 2013-2021 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -34,9 +34,9 @@
 class Resolver : noncopyable
 {
 public:
-  typedef boost::asio::ip::udp protocol;
-  typedef protocol::resolver::iterator iterator;
-  typedef protocol::resolver::query query;
+  using protocol = boost::asio::ip::udp;
+  using iterator = protocol::resolver::iterator;
+  using query = protocol::resolver::query;
 
 public:
   Resolver(boost::asio::io_service& ioService,
@@ -58,7 +58,9 @@
     m_onSuccess = onSuccess;
     m_onError = onError;
 
-    m_resolver.async_resolve(q, bind(&Resolver::onResolveResult, this, _1, _2, self));
+    m_resolver.async_resolve(q, [=] (auto&&... args) {
+      onResolveResult(std::forward<decltype(args)>(args)..., self);
+    });
 
     m_resolveTimeout = m_scheduler.schedule(timeout, [=] { onResolveTimeout(self); });
   }
@@ -122,11 +124,9 @@
   iterator
   selectAddress(iterator it) const
   {
-    while (it != iterator() &&
-           !m_addressSelector(it->endpoint().address())) {
+    while (it != iterator() && !m_addressSelector(it->endpoint().address())) {
       ++it;
     }
-
     return it;
   }
 
@@ -149,7 +149,7 @@
              const AddressSelector& addressSelector,
              time::nanoseconds timeout)
 {
-  auto resolver = make_shared<Resolver>(ref(ioService), addressSelector);
+  auto resolver = make_shared<Resolver>(ioService, addressSelector);
   resolver->asyncResolve(Resolver::query(host, ""), onSuccess, onError, timeout, resolver);
   // resolver will be destroyed when async operation finishes or ioService stops
 }
diff --git a/ndn-cxx/net/face-uri.cpp b/ndn-cxx/net/face-uri.cpp
index 56e5dab..00e1060 100644
--- a/ndn-cxx/net/face-uri.cpp
+++ b/ndn-cxx/net/face-uri.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2020 Regents of the University of California,
+ * Copyright (c) 2013-2021 Regents of the University of California,
  *                         Arizona Board of Regents,
  *                         Colorado State University,
  *                         University Pierre & Marie Curie, Sorbonne University,
@@ -330,8 +330,8 @@
       }
 
       dns::asyncResolve(unescapeHost(faceUri.getHost()),
-        bind(&IpHostCanonizeProvider<Protocol>::onDnsSuccess, this, uri, onSuccess, onFailure, _1),
-        bind(&IpHostCanonizeProvider<Protocol>::onDnsFailure, this, uri, onFailure, _1),
+        [=] (const auto& ipAddr) { onDnsSuccess(uri, onSuccess, onFailure, ipAddr); },
+        [=] (const auto& reason) { onDnsFailure(uri, onFailure, reason); },
         io, addressSelector, timeout);
     }
   }
@@ -382,7 +382,7 @@
   }
 
   void
-  onDnsFailure(const shared_ptr<FaceUri>& faceUri,
+  onDnsFailure(const shared_ptr<FaceUri>&,
                const FaceUri::CanonizeFailureCallback& onFailure,
                const std::string& reason) const
   {
@@ -394,7 +394,7 @@
    *          (false,reason) if the address is not allowable.
    */
   virtual std::pair<bool, std::string>
-  checkAddress(const dns::IpAddress& ipAddress) const
+  checkAddress(const dns::IpAddress&) const
   {
     return {true, ""};
   }
@@ -472,7 +472,7 @@
   canonize(const FaceUri& faceUri,
            const FaceUri::CanonizeSuccessCallback& onSuccess,
            const FaceUri::CanonizeFailureCallback& onFailure,
-           boost::asio::io_service& io, time::nanoseconds timeout) const override
+           boost::asio::io_service&, time::nanoseconds timeout) const override
   {
     auto addr = ethernet::Address::fromString(faceUri.getHost());
     if (addr.isNull()) {
@@ -504,7 +504,7 @@
   canonize(const FaceUri& faceUri,
            const FaceUri::CanonizeSuccessCallback& onSuccess,
            const FaceUri::CanonizeFailureCallback& onFailure,
-           boost::asio::io_service& io, time::nanoseconds timeout) const override
+           boost::asio::io_service&, time::nanoseconds timeout) const override
   {
     if (faceUri.getHost().empty()) {
       onFailure("network interface name is missing");
@@ -550,7 +550,7 @@
   canonize(const FaceUri& faceUri,
            const FaceUri::CanonizeSuccessCallback& onSuccess,
            const FaceUri::CanonizeFailureCallback& onFailure,
-           boost::asio::io_service& io, time::nanoseconds timeout) const override
+           boost::asio::io_service&, time::nanoseconds timeout) const override
   {
     if (this->isCanonical(faceUri)) {
       onSuccess(faceUri);
diff --git a/ndn-cxx/transport/detail/stream-transport-impl.hpp b/ndn-cxx/transport/detail/stream-transport-impl.hpp
index 410e095..4cd1ff1 100644
--- a/ndn-cxx/transport/detail/stream-transport-impl.hpp
+++ b/ndn-cxx/transport/detail/stream-transport-impl.hpp
@@ -179,31 +179,28 @@
   {
     BOOST_ASSERT(!m_transmissionQueue.empty());
     boost::asio::async_write(m_socket, m_transmissionQueue.front(),
-                             bind(&Impl::handleAsyncWrite, this->shared_from_this(), _1,
-                                  m_transmissionQueue.begin()));
-  }
+      // capture a copy of the shared_ptr to "this" to prevent deallocation
+      [this, self = this->shared_from_this(),
+       queueItem = m_transmissionQueue.begin()] (const auto& error, size_t) {
+        if (error) {
+          if (error == boost::system::errc::operation_canceled) {
+            // async receive has been explicitly cancelled (e.g., socket close)
+            return;
+          }
+          m_transport.close();
+          NDN_THROW(Transport::Error(error, "error while writing data to socket"));
+        }
 
-  void
-  handleAsyncWrite(const boost::system::error_code& error, TransmissionQueue::iterator queueItem)
-  {
-    if (error) {
-      if (error == boost::system::errc::operation_canceled) {
-        // async receive has been explicitly cancelled (e.g., socket close)
-        return;
-      }
-      m_transport.close();
-      NDN_THROW(Transport::Error(error, "error while writing data to socket"));
-    }
+        if (!m_transport.m_isConnected) {
+          return; // queue has been already cleared
+        }
 
-    if (!m_transport.m_isConnected) {
-      return; // queue has been already cleared
-    }
+        m_transmissionQueue.erase(queueItem);
 
-    m_transmissionQueue.erase(queueItem);
-
-    if (!m_transmissionQueue.empty()) {
-      asyncWrite();
-    }
+        if (!m_transmissionQueue.empty()) {
+          asyncWrite();
+        }
+      });
   }
 
   void
@@ -211,42 +208,39 @@
   {
     m_socket.async_receive(boost::asio::buffer(m_inputBuffer + m_inputBufferSize,
                                                MAX_NDN_PACKET_SIZE - m_inputBufferSize), 0,
-                           bind(&Impl::handleAsyncReceive, this->shared_from_this(), _1, _2));
-  }
+      // capture a copy of the shared_ptr to "this" to prevent deallocation
+      [this, self = this->shared_from_this()] (const auto& error, size_t nBytesRecvd) {
+        if (error) {
+          if (error == boost::system::errc::operation_canceled) {
+            // async receive has been explicitly cancelled (e.g., socket close)
+            return;
+          }
+          m_transport.close();
+          NDN_THROW(Transport::Error(error, "error while receiving data from socket"));
+        }
 
-  void
-  handleAsyncReceive(const boost::system::error_code& error, std::size_t nBytesRecvd)
-  {
-    if (error) {
-      if (error == boost::system::errc::operation_canceled) {
-        // async receive has been explicitly cancelled (e.g., socket close)
-        return;
-      }
-      m_transport.close();
-      NDN_THROW(Transport::Error(error, "error while receiving data from socket"));
-    }
+        m_inputBufferSize += nBytesRecvd;
+        // do magic
 
-    m_inputBufferSize += nBytesRecvd;
-    // do magic
+        std::size_t offset = 0;
+        bool hasProcessedSome = processAllReceived(m_inputBuffer, offset, m_inputBufferSize);
+        if (!hasProcessedSome && m_inputBufferSize == MAX_NDN_PACKET_SIZE && offset == 0) {
+          m_transport.close();
+          NDN_THROW(Transport::Error("input buffer full, but a valid TLV cannot be decoded"));
+        }
 
-    std::size_t offset = 0;
-    bool hasProcessedSome = processAllReceived(m_inputBuffer, offset, m_inputBufferSize);
-    if (!hasProcessedSome && m_inputBufferSize == MAX_NDN_PACKET_SIZE && offset == 0) {
-      m_transport.close();
-      NDN_THROW(Transport::Error("input buffer full, but a valid TLV cannot be decoded"));
-    }
+        if (offset > 0) {
+          if (offset != m_inputBufferSize) {
+            std::copy(m_inputBuffer + offset, m_inputBuffer + m_inputBufferSize, m_inputBuffer);
+            m_inputBufferSize -= offset;
+          }
+          else {
+            m_inputBufferSize = 0;
+          }
+        }
 
-    if (offset > 0) {
-      if (offset != m_inputBufferSize) {
-        std::copy(m_inputBuffer + offset, m_inputBuffer + m_inputBufferSize, m_inputBuffer);
-        m_inputBufferSize -= offset;
-      }
-      else {
-        m_inputBufferSize = 0;
-      }
-    }
-
-    asyncReceive();
+        asyncReceive();
+      });
   }
 
   bool
diff --git a/ndn-cxx/util/segment-fetcher.cpp b/ndn-cxx/util/segment-fetcher.cpp
index f435167..60fdc2a 100644
--- a/ndn-cxx/util/segment-fetcher.cpp
+++ b/ndn-cxx/util/segment-fetcher.cpp
@@ -239,9 +239,8 @@
   afterSegmentReceived(data);
 
   m_validator.validate(data,
-                       bind(&SegmentFetcher::afterValidationSuccess, this, _1, origInterest,
-                            pendingSegmentIt, weakSelf),
-                       bind(&SegmentFetcher::afterValidationFailure, this, _1, _2, weakSelf));
+    [=] (const Data& d) { afterValidationSuccess(d, origInterest, pendingSegmentIt, weakSelf); },
+    [=] (const Data& d, const auto& error) { afterValidationFailure(d, error, weakSelf); });
 }
 
 void
@@ -323,7 +322,7 @@
 }
 
 void
-SegmentFetcher::afterValidationFailure(const Data& data,
+SegmentFetcher::afterValidationFailure(const Data&,
                                        const security::ValidationError& error,
                                        const weak_ptr<SegmentFetcher>& weakSelf)
 {
diff --git a/ndn-cxx/util/segment-fetcher.hpp b/ndn-cxx/util/segment-fetcher.hpp
index eadb426..9e7476b 100644
--- a/ndn-cxx/util/segment-fetcher.hpp
+++ b/ndn-cxx/util/segment-fetcher.hpp
@@ -71,24 +71,11 @@
  * been successfully validated, #afterSegmentValidated will be signaled.
  *
  * Example:
- *     @code
- *     void
- *     afterFetchComplete(ConstBufferPtr data)
- *     {
- *       ...
- *     }
- *
- *     void
- *     afterFetchError(uint32_t errorCode, const std::string& errorMsg)
- *     {
- *       ...
- *     }
- *
- *     ...
- *     auto fetcher = SegmentFetcher::start(face, Interest("/data/prefix"), validator);
- *     fetcher->onComplete.connect(bind(&afterFetchComplete, this, _1));
- *     fetcher->onError.connect(bind(&afterFetchError, this, _1, _2));
- *     @endcode
+ * @code
+ *   auto fetcher = SegmentFetcher::start(face, Interest("/data/prefix"), validator);
+ *   fetcher->onComplete.connect([] (ConstBufferPtr data) {...});
+ *   fetcher->onError.connect([] (uint32_t errorCode, const std::string& errorMsg) {...});
+ * @endcode
  */
 class SegmentFetcher : noncopyable
 {
diff --git a/tests/unit/face.t.cpp b/tests/unit/face.t.cpp
index f7c6132..eaab9b6 100644
--- a/tests/unit/face.t.cpp
+++ b/tests/unit/face.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2020 Regents of the University of California.
+ * Copyright (c) 2013-2021 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -35,6 +35,7 @@
 namespace tests {
 
 using ndn::util::DummyClientFace;
+using std::bind;
 
 struct WantPrefixRegReply;
 struct NoPrefixRegReply;
diff --git a/tests/unit/mgmt/dispatcher.t.cpp b/tests/unit/mgmt/dispatcher.t.cpp
index a6054c2..7827516 100644
--- a/tests/unit/mgmt/dispatcher.t.cpp
+++ b/tests/unit/mgmt/dispatcher.t.cpp
@@ -31,6 +31,7 @@
 namespace tests {
 
 using namespace ndn::tests;
+using std::bind;
 
 class DispatcherFixture : public IoKeyChainFixture
 {
diff --git a/tests/unit/mgmt/nfd/controller-fixture.hpp b/tests/unit/mgmt/nfd/controller-fixture.hpp
index 77c7620..764ff41 100644
--- a/tests/unit/mgmt/nfd/controller-fixture.hpp
+++ b/tests/unit/mgmt/nfd/controller-fixture.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2020 Regents of the University of California.
+ * Copyright (c) 2013-2021 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -42,8 +42,8 @@
     : face(m_io, m_keyChain)
     , m_validator(true)
     , controller(face, m_keyChain, m_validator)
-    , commandFailCallback(bind(&ControllerFixture::recordCommandFail, this, _1))
-    , datasetFailCallback(bind(&ControllerFixture::recordDatasetFail, this, _1, _2))
+    , commandFailCallback([this] (const auto& resp) { failCodes.push_back(resp.getCode()); })
+    , datasetFailCallback([this] (auto code, const auto&) { failCodes.push_back(code); })
   {
     m_keyChain.setDefaultIdentity(m_keyChain.createIdentity("/localhost/ControllerFixture"));
   }
@@ -59,19 +59,6 @@
     m_validator.getPolicy().setResult(shouldAccept);
   }
 
-private:
-  void
-  recordCommandFail(const ControlResponse& response)
-  {
-    failCodes.push_back(response.getCode());
-  }
-
-  void
-  recordDatasetFail(uint32_t code, const std::string& reason)
-  {
-    failCodes.push_back(code);
-  }
-
 protected:
   ndn::util::DummyClientFace face;
   DummyValidator m_validator;
diff --git a/tests/unit/mgmt/nfd/controller.t.cpp b/tests/unit/mgmt/nfd/controller.t.cpp
index b0a5838..83deb23 100644
--- a/tests/unit/mgmt/nfd/controller.t.cpp
+++ b/tests/unit/mgmt/nfd/controller.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2020 Regents of the University of California.
+ * Copyright (c) 2013-2021 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -37,11 +37,6 @@
 class CommandFixture : public ControllerFixture
 {
 protected:
-  CommandFixture()
-    : succeedCallback(bind(&CommandFixture::succeed, this, _1))
-  {
-  }
-
   void
   respond(const ControlResponse& responsePayload)
   {
@@ -51,15 +46,10 @@
     this->advanceClocks(1_ms);
   }
 
-private:
-  void
-  succeed(const ControlParameters& parameters)
-  {
-    succeeds.push_back(parameters);
-  }
-
 protected:
-  Controller::CommandSucceedCallback succeedCallback;
+  Controller::CommandSucceedCallback succeedCallback = [this] (const auto& params) {
+    succeeds.push_back(params);
+  };
   std::vector<ControlParameters> succeeds;
 };
 
diff --git a/tests/unit/mgmt/status-dataset-context.t.cpp b/tests/unit/mgmt/status-dataset-context.t.cpp
index 58c8382..6d1e0b9 100644
--- a/tests/unit/mgmt/status-dataset-context.t.cpp
+++ b/tests/unit/mgmt/status-dataset-context.t.cpp
@@ -229,13 +229,7 @@
 class AbnormalStateTestFixture
 {
 protected:
-  AbnormalStateTestFixture()
-    : context(Interest("/abnormal-state"), bind([]{}), bind([]{}))
-  {
-  }
-
-protected:
-  StatusDatasetContext context;
+  StatusDatasetContext context{Interest("/abnormal-state"), [] (auto&&...) {}, [] (auto&&...) {}};
 };
 
 BOOST_FIXTURE_TEST_SUITE(AbnormalState, AbnormalStateTestFixture)
diff --git a/tests/unit/net/dns.t.cpp b/tests/unit/net/dns.t.cpp
index db834c0..374eeea 100644
--- a/tests/unit/net/dns.t.cpp
+++ b/tests/unit/net/dns.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2021 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -36,12 +36,6 @@
 class DnsFixture
 {
 public:
-  DnsFixture()
-    : m_nFailures(0)
-    , m_nSuccesses(0)
-  {
-  }
-
   void
   onSuccess(const IpAddress& resolvedAddress,
             const IpAddress& expectedAddress,
@@ -51,7 +45,7 @@
     ++m_nSuccesses;
 
     if (!isValid) {
-      BOOST_FAIL("Resolved to " + resolvedAddress.to_string() + ", but should have failed");
+      BOOST_ERROR("Resolved to " + resolvedAddress.to_string() + ", but should have failed");
     }
 
     BOOST_CHECK_EQUAL(resolvedAddress.is_v4(), expectedAddress.is_v4());
@@ -64,20 +58,15 @@
   }
 
   void
-  onFailure(bool isValid)
+  onFailure(bool shouldFail)
   {
     ++m_nFailures;
-
-    if (!isValid) {
-      BOOST_FAIL("Resolution should not have failed");
-    }
-
-    BOOST_CHECK_MESSAGE(true, "Resolution failed as expected");
+    BOOST_CHECK_MESSAGE(shouldFail, "Resolution should not have failed");
   }
 
 protected:
-  uint32_t m_nFailures;
-  uint32_t m_nSuccesses;
+  int m_nFailures = 0;
+  int m_nSuccesses = 0;
   boost::asio::io_service m_ioService;
 };
 
@@ -89,8 +78,8 @@
   SKIP_IF_IP_UNAVAILABLE();
 
   asyncResolve("nothost.nothost.nothost.arpa",
-               bind(&DnsFixture::onSuccess, this, _1, IpAddress(address_v4()), false, false),
-               bind(&DnsFixture::onFailure, this, true),
+               std::bind(&DnsFixture::onSuccess, this, _1, IpAddress(address_v4()), false, false),
+               [this] (auto&&...) { onFailure(true); },
                m_ioService); // should fail
 
   m_ioService.run();
@@ -103,9 +92,9 @@
   SKIP_IF_IPV4_UNAVAILABLE();
 
   asyncResolve("192.0.2.1",
-               bind(&DnsFixture::onSuccess, this, _1,
-                    IpAddress(address_v4::from_string("192.0.2.1")), true, true),
-               bind(&DnsFixture::onFailure, this, false),
+               std::bind(&DnsFixture::onSuccess, this, _1,
+                         IpAddress(address_v4::from_string("192.0.2.1")), true, true),
+               [this] (auto&&...) { onFailure(false); },
                m_ioService);
 
   m_ioService.run();
@@ -118,15 +107,15 @@
   SKIP_IF_IPV6_UNAVAILABLE();
 
   asyncResolve("ipv6.google.com", // only IPv6 address should be available
-               bind(&DnsFixture::onSuccess, this, _1, IpAddress(address_v6()), true, false),
-               bind(&DnsFixture::onFailure, this, false),
+               std::bind(&DnsFixture::onSuccess, this, _1, IpAddress(address_v6()), true, false),
+               [this] (auto&&...) { onFailure(false); },
                m_ioService);
 
   asyncResolve("2001:db8:3f9:0:3025:ccc5:eeeb:86d3",
-               bind(&DnsFixture::onSuccess, this, _1,
-                    IpAddress(address_v6::from_string("2001:db8:3f9:0:3025:ccc5:eeeb:86d3")),
-                    true, true),
-               bind(&DnsFixture::onFailure, this, false),
+               std::bind(&DnsFixture::onSuccess, this, _1,
+                         IpAddress(address_v6::from_string("2001:db8:3f9:0:3025:ccc5:eeeb:86d3")),
+                         true, true),
+               [this] (auto&&...) { onFailure(false); },
                m_ioService);
 
   m_ioService.run();
@@ -140,28 +129,28 @@
   SKIP_IF_IPV6_UNAVAILABLE();
 
   asyncResolve("www.named-data.net",
-               bind(&DnsFixture::onSuccess, this, _1, IpAddress(address_v4()), true, false),
-               bind(&DnsFixture::onFailure, this, false),
+               std::bind(&DnsFixture::onSuccess, this, _1, IpAddress(address_v4()), true, false),
+               [this] (auto&&...) { onFailure(false); },
                m_ioService, Ipv4Only());
 
   asyncResolve("a.root-servers.net",
-               bind(&DnsFixture::onSuccess, this, _1, IpAddress(address_v4()), true, false),
-               bind(&DnsFixture::onFailure, this, false),
+               std::bind(&DnsFixture::onSuccess, this, _1, IpAddress(address_v4()), true, false),
+               [this] (auto&&...) { onFailure(false); },
                m_ioService, Ipv4Only()); // request IPv4 address
 
   asyncResolve("a.root-servers.net",
-               bind(&DnsFixture::onSuccess, this, _1, IpAddress(address_v6()), true, false),
-               bind(&DnsFixture::onFailure, this, false),
+               std::bind(&DnsFixture::onSuccess, this, _1, IpAddress(address_v6()), true, false),
+               [this] (auto&&...) { onFailure(false); },
                m_ioService, Ipv6Only()); // request IPv6 address
 
   asyncResolve("ipv6.google.com", // only IPv6 address should be available
-               bind(&DnsFixture::onSuccess, this, _1, IpAddress(address_v6()), true, false),
-               bind(&DnsFixture::onFailure, this, false),
+               std::bind(&DnsFixture::onSuccess, this, _1, IpAddress(address_v6()), true, false),
+               [this] (auto&&...) { onFailure(false); },
                m_ioService, Ipv6Only());
 
   asyncResolve("ipv6.google.com", // only IPv6 address should be available
-               bind(&DnsFixture::onSuccess, this, _1, IpAddress(address_v6()), false, false),
-               bind(&DnsFixture::onFailure, this, true),
+               std::bind(&DnsFixture::onSuccess, this, _1, IpAddress(address_v6()), false, false),
+               [this] (auto&&...) { onFailure(true); },
                m_ioService, Ipv4Only()); // should fail
 
   m_ioService.run();
diff --git a/tests/unit/net/face-uri.t.cpp b/tests/unit/net/face-uri.t.cpp
index c8f7d16..76af381 100644
--- a/tests/unit/net/face-uri.t.cpp
+++ b/tests/unit/net/face-uri.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2020 Regents of the University of California,
+ * Copyright (c) 2013-2021 Regents of the University of California,
  *                         Arizona Board of Regents,
  *                         Colorado State University,
  *                         University Pierre & Marie Curie, Sorbonne University,
@@ -69,8 +69,8 @@
     auto tc = make_shared<CanonizeTestCase>(request, shouldSucceed, expectedUri);
 
     FaceUri uri(request);
-    uri.canonize(bind(&CanonizeFixture::onCanonizeSuccess, this, tc, _1),
-                 bind(&CanonizeFixture::onCanonizeFailure, this, tc, _1),
+    uri.canonize(std::bind(&CanonizeFixture::onCanonizeSuccess, this, tc, _1),
+                 std::bind(&CanonizeFixture::onCanonizeFailure, this, tc, _1),
                  m_io, 10_s);
   }
 
diff --git a/tests/unit/security/certificate-fetcher-from-network.t.cpp b/tests/unit/security/certificate-fetcher-from-network.t.cpp
index caf941a..36a1ae9 100644
--- a/tests/unit/security/certificate-fetcher-from-network.t.cpp
+++ b/tests/unit/security/certificate-fetcher-from-network.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2020 Regents of the University of California.
+ * Copyright (c) 2013-2021 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -65,7 +65,7 @@
     interest.setCanBePrefix(false);
     m_keyChain.sign(interest, signingByIdentity(subSubIdentity));
 
-    processInterest = bind(&CertificateFetcherFromNetworkFixture<Response>::makeResponse, this, _1);
+    processInterest = [this] (const Interest& i) { makeResponse(i); };
   }
 
   void
diff --git a/tests/unit/security/validator-fixture.cpp b/tests/unit/security/validator-fixture.cpp
index 8bb4713..7a7ee14 100644
--- a/tests/unit/security/validator-fixture.cpp
+++ b/tests/unit/security/validator-fixture.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2020 Regents of the University of California.
+ * Copyright (c) 2013-2021 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -46,7 +46,7 @@
 {
   util::signal::ScopedConnection conn = face.onSendInterest.connect([this] (const Interest& interest) {
     if (processInterest) {
-      m_io.post(bind(processInterest, interest));
+      m_io.post([=] { processInterest(interest); });
     }
   });
   advanceClocks(s_mockPeriod, s_mockTimes);
diff --git a/tests/unit/security/validator-null.t.cpp b/tests/unit/security/validator-null.t.cpp
index 9d04cb8..8fc5a5e 100644
--- a/tests/unit/security/validator-null.t.cpp
+++ b/tests/unit/security/validator-null.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2020 Regents of the University of California.
+ * Copyright (c) 2013-2021 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -28,6 +28,8 @@
 namespace security {
 namespace tests {
 
+using std::bind;
+
 BOOST_AUTO_TEST_SUITE(Security)
 BOOST_FIXTURE_TEST_SUITE(TestValidatorNull, ndn::tests::KeyChainFixture)
 
diff --git a/tests/unit/util/notification-subscriber.t.cpp b/tests/unit/util/notification-subscriber.t.cpp
index d8f9dfd..3936e9e 100644
--- a/tests/unit/util/notification-subscriber.t.cpp
+++ b/tests/unit/util/notification-subscriber.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2020 Regents of the University of California,
+ * Copyright (c) 2014-2021 Regents of the University of California,
  *                         Arizona Board of Regents,
  *                         Colorado State University,
  *                         University Pierre & Marie Curie, Sorbonne University,
@@ -74,45 +74,16 @@
   void
   deliverNack(const Interest& interest, const lp::NackReason& reason)
   {
-    lp::Nack nack = makeNack(interest, reason);
-    subscriberFace.receive(nack);
-  }
-
-  void
-  afterNotification(const SimpleNotification& notification)
-  {
-    lastNotification = notification;
-  }
-
-  void
-  afterNack(const lp::Nack& nack)
-  {
-    lastNack = nack;
-  }
-
-  void
-  afterTimeout()
-  {
-    hasTimeout = true;
-  }
-
-  void
-  afterDecodeError(const Data& data)
-  {
-    lastDecodeErrorData = data;
+    subscriberFace.receive(makeNack(interest, reason));
   }
 
   void
   connectHandlers()
   {
-    notificationConn = subscriber.onNotification.connect(
-      bind(&NotificationSubscriberFixture::afterNotification, this, _1));
-    nackConn = subscriber.onNack.connect(
-      bind(&NotificationSubscriberFixture::afterNack, this, _1));
-    subscriber.onTimeout.connect(
-      bind(&NotificationSubscriberFixture::afterTimeout, this));
-    subscriber.onDecodeError.connect(
-      bind(&NotificationSubscriberFixture::afterDecodeError, this, _1));
+    notificationConn = subscriber.onNotification.connect([this] (const auto& n) { lastNotification = n; });
+    nackConn = subscriber.onNack.connect([this] (const auto& nack) { lastNack = nack; });
+    subscriber.onTimeout.connect([this] { hasTimeout = true; });
+    subscriber.onDecodeError.connect([this] (const auto& data) { lastDecodeErrorData = data; });
   }
 
   void
diff --git a/tests/unit/util/scheduler.t.cpp b/tests/unit/util/scheduler.t.cpp
index 12f018a..1040b92 100644
--- a/tests/unit/util/scheduler.t.cpp
+++ b/tests/unit/util/scheduler.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2020 Regents of the University of California.
+ * Copyright (c) 2013-2021 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -109,7 +109,7 @@
   void
   reschedule()
   {
-    EventId eventId = scheduler.schedule(100_ms, bind(&SelfRescheduleFixture::reschedule, this));
+    EventId eventId = scheduler.schedule(100_ms, [this] { reschedule(); });
     selfEventId.cancel();
     selfEventId = eventId;
 
@@ -125,7 +125,7 @@
     selfEventId.cancel();
 
     if (count < 5)  {
-      selfEventId = scheduler.schedule(100_ms, bind(&SelfRescheduleFixture::reschedule2, this));
+      selfEventId = scheduler.schedule(100_ms, [this] { reschedule2(); });
       count++;
     }
   }
@@ -150,21 +150,21 @@
 
 BOOST_FIXTURE_TEST_CASE(Reschedule, SelfRescheduleFixture)
 {
-  selfEventId = scheduler.schedule(0_s, bind(&SelfRescheduleFixture::reschedule, this));
+  selfEventId = scheduler.schedule(0_s, [this] { reschedule(); });
   BOOST_REQUIRE_NO_THROW(advanceClocks(50_ms, 1000_ms));
   BOOST_CHECK_EQUAL(count, 5);
 }
 
 BOOST_FIXTURE_TEST_CASE(Reschedule2, SelfRescheduleFixture)
 {
-  selfEventId = scheduler.schedule(0_s, bind(&SelfRescheduleFixture::reschedule2, this));
+  selfEventId = scheduler.schedule(0_s, [this] { reschedule2(); });
   BOOST_REQUIRE_NO_THROW(advanceClocks(50_ms, 1000_ms));
   BOOST_CHECK_EQUAL(count, 5);
 }
 
 BOOST_FIXTURE_TEST_CASE(Reschedule3, SelfRescheduleFixture)
 {
-  selfEventId = scheduler.schedule(0_s, bind(&SelfRescheduleFixture::reschedule3, this));
+  selfEventId = scheduler.schedule(0_s, [this] { reschedule3(); });
   BOOST_REQUIRE_NO_THROW(advanceClocks(50_ms, 1000_ms));
   BOOST_CHECK_EQUAL(count, 6);
 }
diff --git a/tests/unit/util/segment-fetcher.t.cpp b/tests/unit/util/segment-fetcher.t.cpp
index c58c1f9..55247fe 100644
--- a/tests/unit/util/segment-fetcher.t.cpp
+++ b/tests/unit/util/segment-fetcher.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2020 Regents of the University of California.
+ * Copyright (c) 2013-2021 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -36,6 +36,7 @@
 namespace tests {
 
 using namespace ndn::tests;
+using std::bind;
 
 class SegmentFetcherFixture : public IoKeyChainFixture
 {