diff --git a/src/libs/utils/algorithm.h b/src/libs/utils/algorithm.h
index 5efaed2343bbc65c74cd19d4604799c8a54870d0..f918d996681213b5093b203a538fafd6b2e77ce2 100644
--- a/src/libs/utils/algorithm.h
+++ b/src/libs/utils/algorithm.h
@@ -200,95 +200,137 @@ struct RemoveCvAndReference
     typedef typename std::remove_cv<typename std::remove_reference<T>::type>::type type;
 };
 
-template<typename F, typename T>
-struct ResultOfFunctionWithoutCvAndReference
+// abstraction to treat Container<T> and QStringList similarly
+template<typename T>
+struct ContainerType
 {
-    typedef typename RemoveCvAndReference<decltype(declval<F>()(declval<T>()))>::type type;
+
 };
 
-// actual implementation of transform
-template<template<typename> class C, // result container type
-         template<typename> class SC, // input container type
-         typename T, // element type of input container
-         typename F> // function type
-Q_REQUIRED_RESULT
-auto transform_impl(const SC<T> &container, F function)
-     -> C<typename ResultOfFunctionWithoutCvAndReference<F, T>::type>
+// specialization for qt container T_Container<T_Type>
+template<template<typename> class T_Container, typename T_Type>
+struct ContainerType<T_Container<T_Type>> {
+    typedef T_Type ElementType;
+
+    template<class NewElementType>
+    struct WithElementType
+    {
+        typedef T_Container<NewElementType> type;
+    };
+};
+
+// specialization for QStringList
+template<>
+struct ContainerType<QStringList>
 {
-    C<typename ResultOfFunctionWithoutCvAndReference<F, T>::type> result;
-    result.reserve(container.size());
-    std::transform(container.begin(), container.end(),
-                   inserter(result),
-                   function);
-    return result;
-}
+    typedef QString ElementType;
+
+    template<class NewElementType>
+    struct WithElementType
+    {
+        typedef QList<NewElementType> type;
+    };
+};
 
 }
 
-// transform taking a member function pointer
-template<template<typename> class C,
-        typename T,
-        typename R,
-        typename S>
+// actual implementation of transform
+template<typename C, // result container type
+         typename SC> // input container type
+struct TransformImpl {
+    template <typename F>
+    Q_REQUIRED_RESULT
+    static C call(const SC &container, F function)
+    {
+        C result;
+        result.reserve(container.size());
+        std::transform(container.begin(), container.end(),
+                       inserter(result),
+                       function);
+        return result;
+    }
+
+    template <typename R, typename S>
+    Q_REQUIRED_RESULT
+    static C call(const SC &container, R (S::*p)() const)
+    {
+        return call(container, std::mem_fn(p));
+    }
+
+};
+
+// same container type for input and output, e.g. transforming a QList<QString> into QList<int>
+// or QStringList -> QList<>
+template<typename C, // container
+         typename F>
 Q_REQUIRED_RESULT
-auto transform(const C<T> &container, R (S::*p)() const)
-    -> C<typename RemoveCvAndReference<R>::type>
+auto transform(const C &container, F function)
+-> typename ContainerType<C>::template WithElementType< // the type C<stripped return type of F>
+        typename RemoveCvAndReference< // the return type of F stripped
+            decltype(declval<F>()(declval<typename ContainerType<C>::ElementType>())) // the return type of F
+        >::type
+    >::type
 {
-    C<typename RemoveCvAndReference<R>::type> result;
-    result.reserve(container.size());
-    std::transform(container.begin(), container.end(),
-                   std::back_inserter(result),
-                   std::mem_fn(p));
-    return result;
+    return TransformImpl<
+                typename ContainerType<C>::template WithElementType< // the type C<stripped return type>
+                    typename RemoveCvAndReference< // the return type stripped
+                        decltype(declval<F>()(declval<typename ContainerType<C>::ElementType>())) // the return type of F
+                    >::type
+                >::type,
+                C
+            >::call(container, function);
 }
 
-// same container type for input and output, e.g. transforming a QList<QString> into QList<int>
-template<template<typename> class C, // container
-         typename T, // element type
-         typename F> // function type
+// same container type for member function pointer
+template<typename C,
+        typename R,
+        typename S>
 Q_REQUIRED_RESULT
-auto transform(const C<T> &container, F function)
-     -> C<typename RemoveCvAndReference<decltype(declval<F>()(declval<T>()))>::type>
+auto transform(const C &container, R (S::*p)() const)
+    ->typename ContainerType<C>::template WithElementType<typename RemoveCvAndReference<R>::type>::type
 {
-    return transform_impl<QList>(container, function);
+    return TransformImpl<
+                typename ContainerType<C>::template WithElementType< // the type C<stripped R>
+                    typename RemoveCvAndReference<R>::type // stripped R
+                >::type,
+                C
+            >::call(container, p);
 }
 
 // different container types for input and output, e.g. transforming a QList into a QSet
 template<template<typename> class C, // result container type
-         template<typename> class SC, // input container type
-         typename T, // element type of input container
+         typename SC, // input container type
          typename F> // function type
 Q_REQUIRED_RESULT
-auto transform(const SC<T> &container, F function)
-     -> C<typename RemoveCvAndReference<decltype(declval<F>()(declval<T>()))>::type>
+auto transform(const SC &container, F function)
+     -> C< // container C<stripped return type of F>
+            typename RemoveCvAndReference< // stripped return type of F
+                decltype(declval<F>()(declval<typename ContainerType<SC>::ElementType>())) // return type of F
+            >::type>
 {
-    return transform_impl(container, function);
+    return TransformImpl<
+                C< // result container type
+                    typename RemoveCvAndReference< // stripped
+                        decltype(declval<F>()(declval<typename ContainerType<SC>::ElementType>())) // return type of F
+                    >::type>,
+                SC
+            >::call(container, function);
 }
 
-
-//////////
-// transform for QStringList, because that isn't a specialization but a separate type
-// and g++ doesn't want to use the above templates for that
-// clang and msvc do find the base class QList<QString>
-//////////
-
-// QStringList -> QList<>
-template<typename F> // function type
-Q_REQUIRED_RESULT
-auto transform(const QStringList &container, F function)
-     -> QList<typename RemoveCvAndReference<decltype(declval<F>()(declval<QString>()))>::type>
-{
-    return transform_impl<QList>(QList<QString>(container), function);
-}
-
-// QStringList -> any container type
+// different container types for input and output, e.g. transforming a QList into a QSet
+// for member function pointers
 template<template<typename> class C, // result container type
-         typename F> // function type
+         typename SC, // input container type
+         typename R,
+         typename S>
 Q_REQUIRED_RESULT
-auto transform(const QStringList &container, F function)
-     -> C<typename RemoveCvAndReference<decltype(declval<F>()(declval<QString>()))>::type>
+auto transform(const SC &container, R (S::*p)())
+     -> C<typename RemoveCvAndReference<R>::type>
 {
-    return transform_impl<C>(QList<QString>(container), function);
+    return TransformImpl<
+                C<typename RemoveCvAndReference<R>::type>,
+                SC
+            >::call(container, p);
 }
 
 //////////////////