$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Howard Hinnant (hinnant_at_[hidden])
Date: 2005-01-01 12:08:41
On Dec 22, 2004, at 8:29 AM, Thorsten Ottosen wrote:
> The following trait is supposed to make it easier to forward
> arguments in generic code and in particular string literals. For 
> example, I
> will use it when I update boost.assign
> to use const T& arguments instead of T arguments. It could also be 
> used to
> make a better version of std::make_pair():
>
>   template< class F, class S >
>     inline std::pair< typename decayed<F>::type,
>                       typename decayed<S>::type >
>     make_pair( const F& f, const S& s )
>     {
>         return std::pair< typename decayed<F>::type,
>                           typename decayed<S>::type >( f, s );
>     }
>
> Any thoughts from the type_traits authors?
I think decayed is an excellent trait.  Your implementation should be 
modified to also take care of functions converting into function 
pointers though.  It's a shame about the const qaulifier in your 
example make_pair messing up the int[10] conversion to int*.  But with 
an eye towards the future, I think decayed will still eventually 
improve make_pair:
template <class T, class U>
inline
pair<typename decayed<typename remove_reference<T>::type>::type,
      typename decayed<typename remove_reference<U>::type>::type>
make_pair(T&& t, U&& u)
{
     typedef typename decayed<typename remove_reference<T>::type>::type 
dT;
     typedef typename decayed<typename remove_reference<U>::type>::type 
dU;
     return pair<dT, dU>(std::forward<T>(t), std::forward<U>(u));
}
This alternative will mimic the present (by value) make_pair, and work 
with:
     int array[10];
     std::pair<int*,int*> p5 = std::make_pair( array, array );
It will also move from rvalue arguments such as string or vector making 
it more efficient (assuming a move-aware pair in the future).
decayed has my vote for a useful trait (especially assuming an rvalue 
reference).
On Jan 1, 2005, at 10:40 AM, Pavel Vozenilek wrote:
> - following compiles:
>
> struct ABC {
>     explicit ABC(int) {}
> };
> std::pair<ABC, ABC> p5 = boost::make_pair(1, 2);
> std::pair<ABC, ABC> p5 = std::make_pair(1, 2); // also compiles
>
> Maybe the boost::make_pair could be coded
> somehow to disable this behavior (ABC constructor
> is explicit).
This is a characteristic of pair, not make_pair.  And it could be 
disabled by restricting the member template constructor in:
template <class T1, class T2>
struct pair {
   typedef T1 first_type;
   typedef T2 second_type;
   T1 first;
   T2 second;
   pair();
   pair(const T1& x, const T2& y);
   template<class U, class V> pair(const pair<U, V> &p);
};
such that is_convertible<U, T1> and is_convertible<V, T2>, which is a 
change I would support.
-Howard