
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