Index: uspace/lib/cpp/include/impl/functional.hpp
===================================================================
--- uspace/lib/cpp/include/impl/functional.hpp	(revision bdc981b1a25ddf9e96ee24f87ceb6f3954eb2c8c)
+++ uspace/lib/cpp/include/impl/functional.hpp	(revision 6283bf154f9194ffc532013fcc7cc95260eb3d3e)
@@ -30,4 +30,5 @@
 #define LIBCPP_FUNCTIONAL
 
+#include <internal/functional/conditional_function_typedefs.hpp>
 #include <internal/functional/invoke.hpp>
 #include <limits>
@@ -639,6 +640,6 @@
         template<class F>
         class mem_fn_t
-        {
-            // TODO: conditional typedefs
+            : public conditional_function_typedefs<remove_cv_t<remove_reference_t<T>>>
+        {
             public:
                 mem_fn_t(F f)
Index: uspace/lib/cpp/include/internal/functional/conditional_function_typedefs.hpp
===================================================================
--- uspace/lib/cpp/include/internal/functional/conditional_function_typedefs.hpp	(revision 6283bf154f9194ffc532013fcc7cc95260eb3d3e)
+++ uspace/lib/cpp/include/internal/functional/conditional_function_typedefs.hpp	(revision 6283bf154f9194ffc532013fcc7cc95260eb3d3e)
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_INTERNAL_FUNCTION_CONDITIONAL_FUNCTION_TYPEDEFS
+#define LIBCPP_INTERNAL_FUNCTION_CONDITIONAL_FUNCTION_TYPEDEFS
+
+namespace std::aux
+{
+    /**
+     * Note: Some types with possible function-like behavior
+     *       (e.g. function, reference_wrapper, aux::mem_fn_t)
+     *       have to define a type argument type or two types
+     *       first_argument_type and second_argument_type when
+     *       their invocation takes one or two arguments, respectively.
+     *
+     *       The easiest way to conditionally define a type is using
+     *       inheritance and the types below serve exactly for that
+     *       purpose.
+     *
+     *       If we have a type that is specialized as R(Args...)
+     *       for some return type R and argument types Args...,
+     *       we can simply (publicly) inherit from
+     *       conditional_function_typedefs<Args...>. If it is
+     *       templated by some generic type T, we can inherit from
+     *       conditional_function_typedefs<remove_cv_t<remove_reference_t<T>>>
+     *       so that the correct type below gets chosen.
+     */
+
+    template<class... Args>
+    struct conditional_function_typedefs
+    { /* DUMMY BODY */ };
+
+    template<class A>
+    struct conditional_function_typedefs<A>
+    {
+        using argument_type = A;
+    };
+
+    template<class A1, class A2>
+    struct conditional_function_typedefs<A1, A2>
+    {
+        using first_argument_type  = A1;
+        using second_argument_type = A2;
+    };
+
+    template<class R, class... Args>
+    struct conditional_function_typedefs<R(Args...)>
+        : conditional_function_typedefs<Args...>
+    { /* DUMMY BODY */ };
+}
+
+#endif
Index: uspace/lib/cpp/include/internal/functional/function.hpp
===================================================================
--- uspace/lib/cpp/include/internal/functional/function.hpp	(revision bdc981b1a25ddf9e96ee24f87ceb6f3954eb2c8c)
+++ uspace/lib/cpp/include/internal/functional/function.hpp	(revision 6283bf154f9194ffc532013fcc7cc95260eb3d3e)
@@ -30,4 +30,5 @@
 #define LIBCPP_INTERNAL_FUNCTIONAL_FUNCTION
 
+#include <internal/functional/conditional_function_typedefs.hpp>
 #include <internal/functional/reference_wrapper.hpp>
 #include <typeinfo>
@@ -94,8 +95,8 @@
     template<class R, class... Args>
     class function<R(Args...)>
+        : public aux::conditional_function_typedefs<Args...>
     {
         public:
             using result_type = R;
-            // TODO: conditional typedefs
 
             /**
Index: uspace/lib/cpp/include/internal/functional/reference_wrapper.hpp
===================================================================
--- uspace/lib/cpp/include/internal/functional/reference_wrapper.hpp	(revision bdc981b1a25ddf9e96ee24f87ceb6f3954eb2c8c)
+++ uspace/lib/cpp/include/internal/functional/reference_wrapper.hpp	(revision 6283bf154f9194ffc532013fcc7cc95260eb3d3e)
@@ -30,4 +30,5 @@
 #define LIBCPP_INTERNAL_FUNCTIONAL_REFERENCE_WRAPPER
 
+#include <internal/functional/conditional_function_typedefs.hpp>
 #include <internal/functional/invoke.hpp>
 #include <type_traits>
@@ -41,8 +42,8 @@
     template<class T>
     class reference_wrapper
+        : public aux::conditional_function_typedefs<remove_cv_t<remove_reference_t<T>>>
     {
         public:
             using type = T;
-            // TODO: conditional typedefs
 
             reference_wrapper(type& val) noexcept
