Topic: Explicit conversion/construction used in pair constructor


Author: richard@ex-parrot.com (Richard Smith)
Date: Fri, 21 May 2004 17:07:01 +0000 (UTC)
Raw View
Prateek R Karandikar wrote:
>
> As given in The C++ Programming Language, Third Edition(17.4.1.2):
> template<class T1, class T2> struct pair {
>  //...
>  template<class U, class V>
>  pair(const pair<U,V> &p) : first(p.first) , second(p.second){}
> };
>
>
> This would *implicitly* convert a std::pair<A,
> std::vector<B>::size_type> to a std::pair<A, vector<B> >, even though the
> std::vector<B>::vector(std::vector<B>::size_type) constructor is
> *explicit*

[...]

> What does the standard say on this point?

Quoting 20.2.2/4 (emphasis mine)

|   template<class U, class V> pair(const pair<U, V> &p);
|
| Effects: Initializes members from the corresponding members of the
| argument, performing *implicit* conversions as needed.

That seems fairly clear to me.  There is no implicit conversion
between vector<A>::size_type and vector<A> therefore I don't think the
Standard allows conversions between pairs of those types.

I think you've found a bug in GCC's Standard Library.  I notice that
Dinkumware's does this too, so maybe I'm wrong and this is legal.

Of course, ideally you would probably want something like
boost::enable_if to get implicit conversions and explicit conversions
as appropriate.  Unfortunately, when I tried this, I got an internal
compiler error from gcc :


  template <class S, class T>
  template <class U, class V>
  pair<S,T>::pair( pair<U, V> const& src,
    boost::enable_if_c<
      boost::is_convertible<U,S>::value &&
      boost::is_convertible<V,T>::value
    > const* = NULL )
    : first( src.first ), second( src.second )
  {}

  template <class S, class T>
  template <class U, class V>
  explicit pair<S,T>::pair( pair<U, V> const& src,
    boost::disable_if_c<
      boost::is_convertible<U,S>::value &&
      boost::is_convertible<V,T>::value
    > const* = NULL )
    : first( src.first ), second( src.second )
  {}

--
Richard Smith

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kprateek88@yahoo.com (Prateek R Karandikar)
Date: Sun, 23 May 2004 00:16:53 +0000 (UTC)
Raw View
Sorry, in my previous post (which hasn't appeared at this time of
writing) I had written that IMO the wording is ambiguous. Actually I
think that the wording allows explicit conversion ( although it isn't
the clearest way of stating it).

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
To iterate is human, to recurse divine.
-L. Peter Deutsch
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kprateek88@yahoo.com (Prateek R Karandikar)
Date: Sun, 23 May 2004 02:11:24 +0000 (UTC)
Raw View
> Quoting 20.2.2/4 (emphasis mine)
>
> |   template<class U, class V> pair(const pair<U, V> &p);
> |
> | Effects: Initializes members from the corresponding members of the
> | argument, performing *implicit* conversions as needed.

When we say initialize something of type A with b, we mean to call
A::A(b), whether it is explicit or not.

std::vector<T> x(1000);

Here x is initialized with 1000. ( At least that is how I understand
"initialize". Does the standard define it some other way?)

So, IMO, had the standard just said "Initializes members from the
corresponding members of the argument", that would have allowed
explicit conversion/construction.

Now, IMO the addition of the phrase "performing implicit conversions
as needed" does not explicitly forbid explicit
conversion/construction.

So (IMO again) the wording seems to be ambiguous.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kprateek88@yahoo.com (Prateek R Karandikar)
Date: Mon, 24 May 2004 03:15:50 +0000 (UTC)
Raw View
Please interpret my previous 2 posts (the ones sent on 22nd May) as if
you read the second one before the first (beacuse I sent them in that
order). Thanks.

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
To iterate is human, to recurse divine.
-L. Peter Deutsch
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kprateek88@yahoo.com (Prateek R Karandikar)
Date: Wed, 19 May 2004 01:20:25 +0000 (UTC)
Raw View
As given in The C++ Programming Language, Third Edition(17.4.1.2):
template<class T1, class T2> struct pair {
 //...
 template<class U, class V>
 pair(const pair<U,V> &p) : first(p.first) , second(p.second){}
};


This would *implicitly* convert a std::pair<A,
std::vector<B>::size_type> to a std::pair<A, vector<B> >, even though
the
std::vector<B>::vector(std::vector<B>::size_type) constructor is
*explicit*, where A and B
are some types. Why isn't the constructor defined in the following
way:

template<class U, class V>
pair(const pair<U,V> &p) : first(implicit_cast<T1>(p.first)) ,
second(implicit_cast<T2>(p.second)){}

,where implicit_cast is defined as:

 template<typename T, typename U>
T implicit_cast(const U &u) {return u;}


This will convert a pair<T1,T2> to a pair<U,V> only when there is an
*implicit* conversion from T1 to U and T2 to V, and not only an
explicit
one.
I saw gcc's <utility> header. The code there is similar to the code
given in TC++PL.

What does the standard say on this point?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]