diff --git a/NumLib/Function/Interpolation.h b/NumLib/Function/Interpolation.h
index 84a95721ca3df52791e55495a9eaae749de9c75a..b687665798bda6b8d2a765d0a72962176fe4e3dd 100644
--- a/NumLib/Function/Interpolation.h
+++ b/NumLib/Function/Interpolation.h
@@ -16,38 +16,75 @@
 namespace NumLib
 {
 
-/**
+namespace detail
+{
+
+//! \see ::NumLib::shapeFunctionInterpolate()
+template<unsigned DOFOffset, typename NodalValues, typename ShapeMatrix>
+void shapeFunctionInterpolate(
+        const NodalValues &/*nodal_values*/,
+        const ShapeMatrix &/*shape_matrix_N*/)
+{}
+
+//! \see ::NumLib::shapeFunctionInterpolate()
+template<unsigned DOFOffset, typename NodalValues, typename ShapeMatrix, typename... ScalarTypes>
+void shapeFunctionInterpolate(
+        const NodalValues &nodal_values,
+        const ShapeMatrix &shape_matrix_N,
+        double& interpolated_value,
+        ScalarTypes&... interpolated_values)
+{
+    auto const num_nodes = shape_matrix_N.size();
+    double iv = 0.0;
+
+    for (auto n=decltype(num_nodes){0}; n<num_nodes; ++n) {
+        iv += nodal_values[DOFOffset*num_nodes+n] * shape_matrix_N[n];
+    }
+
+    interpolated_value = iv;
+
+    shapeFunctionInterpolate<DOFOffset+1>(nodal_values, shape_matrix_N, interpolated_values...);
+}
+
+} // namespace detail
+
+/*!
  * Interpolates variables given at element nodes according to the given shape matrix.
  *
  * This function simply does the usual finite-element interpolation, i.e. multiplication
  * of nodal values with the shape function.
  *
- * @param nodal_values   vector of nodal values, ordered by component
- * @param shape_matrix_N shape matrix of the point to which will be interpolated
- * @param interpolated_values array of addresses to which the interpolated values will be written
+ * \param nodal_values vector of nodal values, ordered by component
+ * \param shape_matrix_N shape matrix of the point to which will be interpolated
+ * \param interpolated_value interpolated value of the first d.o.f. (output parameter)
+ * \param interpolated_values interpolated value of further d.o.f. (output parameter)
+ *
+ * \tparam NodalValues  type of the container where nodal values are stored
+ * \tparam ShapeMatrix  type of the shape matrix \f$N\f$.
+ * \tparam ScalarValues all of the types in this pack must currently be \c double.
+ *
+ * \note
+ * \c nodal_values have to be ordered by component and it is assumed that all passed d.o.f. are
+ * single-component and are interpolated using the same shape function.
  */
-template<typename NodalValues, typename ShapeMatrix, std::size_t NodalDOF>
+template<typename NodalValues, typename ShapeMatrix, typename... ScalarTypes>
 void shapeFunctionInterpolate(
         const NodalValues& nodal_values,
         const ShapeMatrix& shape_matrix_N,
-        std::array<double*, NodalDOF> interpolated_values
+        double& interpolated_value,
+        ScalarTypes&... interpolated_values
         )
 {
+    auto const num_nodal_dof = sizeof...(interpolated_values) + 1;
     auto const num_nodes = shape_matrix_N.size();
 
-    assert(num_nodes*NodalDOF == nodal_values.size());
-
-    for (auto d=decltype(NodalDOF){0}; d<NodalDOF; ++d)
-    {
-        *interpolated_values[d] = 0.0;
+    assert(num_nodes*num_nodal_dof == nodal_values.size());
+    (void) num_nodal_dof; // no warnings when not in debug build
 
-        for (auto n=decltype(num_nodes){0}; n<num_nodes; ++n)
-        {
-            *interpolated_values[d] += nodal_values[d*num_nodes+n] * shape_matrix_N[n];
-        }
-    }
+    detail::shapeFunctionInterpolate<0>(nodal_values, shape_matrix_N, interpolated_value,
+                                        interpolated_values...);
 }
 
-}
+} // namespace NumLib
 
 #endif // NUMLIB_INTERPOLATION_H
diff --git a/Tests/NumLib/TestFunctionInterpolation.cpp b/Tests/NumLib/TestFunctionInterpolation.cpp
index dd43128f41867a126e6a72b594343461cddad83c..c2b951dbfe400f899c06127225fcce39218dfc19 100644
--- a/Tests/NumLib/TestFunctionInterpolation.cpp
+++ b/Tests/NumLib/TestFunctionInterpolation.cpp
@@ -26,7 +26,6 @@ TEST(NumLibFunctionInterpolationTest, TwoVariablesTwoNodes)
 {
     double variable1 = 0.0;
     double variable2 = 0.0;
-    std::array<double*, 2> interpolated_values = {{&variable1, &variable2}};
 
     const std::array<double, 4> nodal_values = {{
         0.0, 1.0,  // for variable1
@@ -36,7 +35,7 @@ TEST(NumLibFunctionInterpolationTest, TwoVariablesTwoNodes)
     const std::array<double, 2> shape_matrix = {{0.25, 0.75}};
 
     NumLib::shapeFunctionInterpolate(nodal_values, shape_matrix,
-                                     interpolated_values);
+                                     variable1, variable2);
 
     ASSERT_EQ(0.75, variable1);
     ASSERT_EQ(0.5,  variable2);
@@ -78,7 +77,6 @@ TEST(NumLibFunctionInterpolationTest, Linear1DElement)
     // actual test
     double variable1 = 0.0;
     double variable2 = 0.0;
-    std::array<double*, 2> interpolated_values = {{&variable1, &variable2}};
 
     const std::array<double, 4> nodal_values = {{
         0.0, 1.0,  // for variable1
@@ -86,7 +84,7 @@ TEST(NumLibFunctionInterpolationTest, Linear1DElement)
     }};
 
     NumLib::shapeFunctionInterpolate(nodal_values, shape_matrix.N,
-                                     interpolated_values);
+                                     variable1, variable2);
 
     const double n0 = shape_matrix.N[0];
     const double n1 = shape_matrix.N[1];