diff --git a/src/util/filter.hpp b/src/util/filter.hpp
index 5fcbd1fd687e9a191f168036fb5925c961743614..6da37f57c175dacfd1a989c4e39a3da6544f47f8 100644
--- a/src/util/filter.hpp
+++ b/src/util/filter.hpp
@@ -32,12 +32,29 @@ namespace impl {
     };
 }
 
+/*
+ * Iterate through a sequence such that dereference only
+ * gives items from the range that satisfy a given predicate.
+ *
+ * Type parameters:
+ *     I      Iterator type
+ *     S      Sentinel type compatible with I
+ *     F      Functional object
+ *
+ * The underlying sequence is described by an iterator of type
+ * I and a sentinel of type S. The predicate has type F.
+ */
+
 template <typename I, typename S, typename F>
 class filter_iterator {
     mutable I inner_;
     S end_;
     mutable bool ok_;
-    mutable uninitialized<F> f_; // always in initialized state post-construction
+
+    // F may be a lambda type, and thus non-copy assignable. The
+    // use of `uninitalized` allows us to work around this limitation;
+    // f_ will always be in an initalized state post-construction.
+    mutable uninitialized<F> f_;
 
     void advance() const {
         if (ok_) return;
diff --git a/src/util/transform.hpp b/src/util/transform.hpp
index ec86ea71d5c46f053711783e21795a78d3904a41..71c49e723017deb92258dc02be21e66da7dd9118 100644
--- a/src/util/transform.hpp
+++ b/src/util/transform.hpp
@@ -26,7 +26,10 @@ class transform_iterator: public iterator_adaptor<transform_iterator<I, F>, I> {
     friend class iterator_adaptor<transform_iterator<I, F>, I>;
 
     I inner_;
-    uninitialized<F> f_; // always in initialized state post-construction
+
+    // F may be a lambda type, and thus non-copy assignable. The
+    // use of `uninitalized` allows us to work around this limitation;
+    uninitialized<F> f_;
 
     // provides access to inner iterator for adaptor.
     const I& inner() const { return inner_; }