Boost logo

Boost :

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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk