diff --git a/CHANGELOG.md b/CHANGELOG.md
index 788153e6dc7dd1dea88fd6d834008314638c955a..5ab54877adfade2a3badc68556416f2a18f3b8a7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,10 @@ SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
 
 # Master (will become release 2.11)
 
+## C++: Changelog
+
+- Add deduction guides to `TupleVector` analogous to `std::tuple`.
+
 # Release 2.10
 
 ## Dependencies
diff --git a/cmake/modules/DuneDoxygen.cmake b/cmake/modules/DuneDoxygen.cmake
index bc383dbdf814f73e74810f8ef5b1223085376a3d..f1fb9fb299d6178db2da3538987f135270f0667d 100644
--- a/cmake/modules/DuneDoxygen.cmake
+++ b/cmake/modules/DuneDoxygen.cmake
@@ -122,9 +122,10 @@ macro(add_doxygen_target)
         set(doxygenfiles \"\${doxygenfiles}\")
         foreach(_file \${doxygenfiles})
            get_filename_component(_basename \${_file} NAME)
+           # Manifest is generated when prefix was set at configuration time, otherwise is skipped
            LIST(APPEND CMAKE_INSTALL_MANIFEST_FILES ${CMAKE_INSTALL_FULL_DOCDIR}/doxygen/\${_basename})
          endforeach()
-         file(INSTALL \${doxygenfiles} DESTINATION ${CMAKE_INSTALL_FULL_DOCDIR}/doxygen)
-         message(STATUS \"Installed doxygen into ${CMAKE_INSTALL_FULL_DOCDIR}/doxygen\")")
+         file(INSTALL \${doxygenfiles} DESTINATION ${CMAKE_INSTALL_DOCDIR}/doxygen)
+         message(STATUS \"Installed doxygen into ${CMAKE_INSTALL_DOCDIR}/doxygen\")")
   endif()
 endmacro(add_doxygen_target)
diff --git a/cmake/modules/FindInkscape.cmake b/cmake/modules/FindInkscape.cmake
index 2e4cf82ac02a7ef3c18dba46432ab0c4e7edf9b9..0922e160b371f8dfba73099ed63ba24e1860bba6 100644
--- a/cmake/modules/FindInkscape.cmake
+++ b/cmake/modules/FindInkscape.cmake
@@ -14,6 +14,12 @@
 #       Path to inkscape to generate .png's form .svg's
 #
 
+# text for feature summary
+include(FeatureSummary)
+set_package_properties("Inkscape" PROPERTIES
+  DESCRIPTION "converts SVG images"
+  URL "www.inkscape.org")
+
 find_program(INKSCAPE inkscape DOC "Path to inkscape to generate png files from svg files")
 find_program(CONVERT convert DOC "Path to convert program")
 if(INKSCAPE)
@@ -26,9 +32,3 @@ if(INKSCAPE)
   endif()
 
 endif(INKSCAPE)
-
-# text for feature summary
-set_package_properties("Inkscape" PROPERTIES
-  DESCRIPTION "converts SVG images"
-  URL "www.inkscape.org"
-  PURPOSE "To generate the documentation with LaTeX")
diff --git a/cmake/modules/UseInkscape.cmake b/cmake/modules/UseInkscape.cmake
index 69eee8b555f3b736d968c8f25dbe7965626ba723..148278b3dfbe2bd8863ef3955ef3698d427d236a 100644
--- a/cmake/modules/UseInkscape.cmake
+++ b/cmake/modules/UseInkscape.cmake
@@ -37,6 +37,8 @@
 #
 include_guard(GLOBAL)
 
+set_package_properties("Inkscape" PROPERTIES
+  PURPOSE "To generate the documentation with LaTeX")
 
 function(dune_create_inkscape_image_converter_target)
   set(OPTION ALL)
diff --git a/dune/common/test/hybridutilitiestest.cc b/dune/common/test/hybridutilitiestest.cc
index baff90d09fa9e926814cafc6430f96d3880f2e45..adbe19996460745e973d25b69c14493fde145dbf 100644
--- a/dune/common/test/hybridutilitiestest.cc
+++ b/dune/common/test/hybridutilitiestest.cc
@@ -261,5 +261,33 @@ int main()
   constexpr auto numberTupleConstexpr = Dune::makeTupleVector(0.25, 2, 3);
   static_assert(sum(numberTupleConstexpr) == 5.25, "Wrong compile time sum!");
 
+  { // CTAD tests
+
+    auto tv0 = Dune::TupleVector{};
+
+    // test construction with values
+    static_assert(std::is_same_v<decltype(tv0),Dune::TupleVector<>>);
+    auto tv1 = Dune::TupleVector{1,2.0,3.0f,4u};
+    static_assert(std::is_same_v<decltype(tv1),Dune::TupleVector<int,double,float,unsigned int>>);
+    auto tv2 = Dune::TupleVector{std::tuple{1,2.0,3.0f,4u}};
+    static_assert(std::is_same_v<decltype(tv2),Dune::TupleVector<int,double,float,unsigned int>>);
+    auto tv3 = Dune::TupleVector{std::pair{1,2.0}};
+    static_assert(std::is_same_v<decltype(tv3),Dune::TupleVector<int,double>>);
+
+    // test construction with l-values
+    Dune::FieldVector<double,2> arg1{};
+    std::vector<float> arg2{};
+    auto tv4 = Dune::TupleVector{arg1,arg2};
+    static_assert(std::is_same_v<decltype(tv4),Dune::TupleVector<Dune::FieldVector<double,2>,std::vector<float>>>);
+
+    // test construction with allocators
+    auto tv5 = Dune::TupleVector{std::allocator_arg_t{}, std::allocator<float>{}, arg1, arg2};
+    static_assert(std::is_same_v<decltype(tv4),decltype(tv5)>);
+    auto tv6 = Dune::TupleVector{std::allocator_arg_t{}, std::allocator<float>{}, std::tuple{arg1, arg2}};
+    static_assert(std::is_same_v<decltype(tv4),decltype(tv6)>);
+    auto tv7 = Dune::TupleVector{std::allocator_arg_t{}, std::allocator<float>{}, std::pair{arg1, arg2}};
+    static_assert(std::is_same_v<decltype(tv4),decltype(tv7)>);
+  }
+
   return test.exit();
 }
diff --git a/dune/common/tuplevector.hh b/dune/common/tuplevector.hh
index dc810ed65b5f72f52e329f1cba540157cc41ee03..a638779f6e9c491ad5904738bc1b2c0611c78e88 100644
--- a/dune/common/tuplevector.hh
+++ b/dune/common/tuplevector.hh
@@ -35,13 +35,6 @@ class TupleVector : public std::tuple<T...>
 {
   using Base = std::tuple<T...>;
 
-  template<class... TT>
-  using TupleConstructorDetector = decltype(Base(std::declval<TT&&>()...));
-
-  template<class... TT>
-  using hasTupleConstructor = Dune::Std::is_detected<TupleConstructorDetector, TT...>;
-
-
 public:
 
   /** \brief Construct from a set of arguments
@@ -51,7 +44,7 @@ public:
    * list.
    */
   template<class... TT,
-    std::enable_if_t<hasTupleConstructor<TT...>::value, int> = 0>
+    class = std::void_t<decltype(Base(std::declval<TT&&>()...))>>
   constexpr TupleVector(TT&&... tt) :
     Base(std::forward<TT>(tt)...)
   {}
@@ -86,6 +79,29 @@ public:
   }
 };
 
+/// \name Deduction guides for TupleVector
+/// \relates TupleVector
+/// @{
+
+template<class... T>
+TupleVector(T...) -> TupleVector<T...>;
+
+template<class T1, class T2>
+TupleVector(std::pair<T1, T2>) -> TupleVector<T1, T2>;
+
+template<class... T>
+TupleVector(std::tuple<T...>) -> TupleVector<T...>;
+
+template <class Alloc, class... T>
+TupleVector(std::allocator_arg_t, Alloc, T...) -> TupleVector<T...>;
+
+template<class Alloc, class T1, class T2>
+TupleVector(std::allocator_arg_t, Alloc, std::pair<T1, T2>) -> TupleVector<T1, T2>;
+
+template<class Alloc, class... T>
+TupleVector(std::allocator_arg_t, Alloc, std::tuple<T...>) -> TupleVector<T...>;
+
+/// @}
 
 
 template<class... T>