Index: template_keyword.hpp
===================================================================
--- template_keyword.hpp	(revision 49439)
+++ template_keyword.hpp	(working copy)
@@ -9,6 +9,8 @@
 # include <boost/mpl/not.hpp>
 # include <boost/type_traits/is_convertible.hpp>
 # include <boost/type_traits/is_reference.hpp>
+# include <boost/type_traits/is_function.hpp>
+# include <boost/type_traits/is_array.hpp>
 
 namespace boost { namespace parameter { 
 
@@ -38,7 +40,26 @@
 {
     typedef Tag key_type;
     typedef T value_type;
-    typedef value_type reference;
+
+    // reference is needed for two reasons: 
+    // 
+    // 1. It is used in the body of arg_list<...>
+    //
+    // 2. It is the result of binding<...>, which we mistakenly told
+    //    people to use instead of value_type<...> to access named
+    //    template parameters
+    // 
+    // It used to be that reference == value_type, but that broke when
+    // the argument was a function or array type, because various
+    // arg_list functions return reference.
+    //
+    // Simply making reference == value_type& would break all the
+    // legacy code that uses binding<...> to access named template
+    // parameters.
+    typedef typename mpl::if_<
+        mpl::or_<is_function<value_type>, is_array<value_type> >
+      , value_type&
+      , value_type>::type reference;
 };
 
 }} // namespace boost::parameter
