Topic: converting ctor in reverse_iterator class template
Author: "subramanian100in@yahoo.com, India" <subramanian100in@yahoo.com>
Date: Thu, 15 Oct 2009 22:15:25 CST Raw View
* On Oct 12, 9:24 pm, Daniel Kr gler <daniel.krueg...@googlemail.com>
wrote:
> On Oct 12, 1:05 am, "subramanian10...@yahoo.com, India"
>
> <subramanian10...@yahoo.com> wrote:
>
> In this case I don't see much harm, because the template constructor
>
> template <class U> reverse_iterator(const reverse_iterator<U>& u);
>
> does not behave completely different as a copy constructor would do.
>
> This is important, because this c'tor will compete with the actual
> copy
> constructor in overload resolution situations.
>
> HTH & Greetings from Bremen,
>
> Daniel Kr gler
>
> --
I am unable to understand the above portion of your reply. That is,
when you say the template ctor will COMPETE with the actual copy ctor
in overload resolution situation, does it mean that if both are
provided it will result in ambiguity error ?
For example, Suppose I have defined
std::reverse_iterator<char*> rc(NULL);
If both the actual ctor and the template ctor were defined and if I
have
std::reverse_iterator<const char*> rcc = rc;
std::reverse_iterator<char*> temp = rc;
will the last two lines result in ambiguity ? Is that what you mean by
saying they will compete in overload resolution ?
Kindly explain with an example.
Thanks
V.Subramanian
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Johannes Schaub (litb)" <schaub-johannes@web.de>
Date: Fri, 16 Oct 2009 09:35:57 CST Raw View
subramanian100in@yahoo.com, India wrote:
> * On Oct 12, 9:24 pm, Daniel Kr gler <daniel.krueg...@googlemail.com>
> wrote:
>> On Oct 12, 1:05 am, "subramanian10...@yahoo.com, India"
>>
>> <subramanian10...@yahoo.com> wrote:
>>
>> In this case I don't see much harm, because the template constructor
>>
>> template <class U> reverse_iterator(const reverse_iterator<U>& u);
>>
>> does not behave completely different as a copy constructor would do.
>>
>> This is important, because this c'tor will compete with the actual
>> copy
>> constructor in overload resolution situations.
>>
>> HTH & Greetings from Bremen,
>>
>> Daniel Kr gler
>>
>> --
>
> I am unable to understand the above portion of your reply. That is,
> when you say the template ctor will COMPETE with the actual copy ctor
> in overload resolution situation, does it mean that if both are
> provided it will result in ambiguity error ?
> For example, Suppose I have defined
> std::reverse_iterator<char*> rc(NULL);
>
> If both the actual ctor and the template ctor were defined and if I
> have
> std::reverse_iterator<const char*> rcc = rc;
> std::reverse_iterator<char*> temp = rc;
>
> will the last two lines result in ambiguity ? Is that what you mean by
> saying they will compete in overload resolution ?
>
In the case of "rcc = rc", the copy constructor is not viable, because it
takes "reverse_iterator<const char*> const&", but the source type is
"reverse_iterator<char*>". Converting this to the parameter cannot be done
only by a standard conversion sequence, and so the only constructor that
remains is the constructor template, which will provide an exact match.
In the case of "temp = rc", the copy constructor and the template both
provide an exact match and no one provides a better match, *but* the copy
constructor is not a template, so it's preferred by overload resolution.
The matter is different if you use direct initialization
std::reverse_iterator<const char*> rcc(rc);
In this case, both candidates are viable, but the copy constructor needs a
user defined conversion sequence to match "rc", while the candidate
generated from the template provides an exact match.
You can artificually construct cases where the template is used:
template<typename T>
struct A {
A() {}
template<typename U>
A(A<U> &u) { ... }
};
A<int> a;
A<int> b = a;
In this case, both the template and the copy constructor provide an exact
match, but the candidate coming from the template has parameter type
"A<int>&", while the copy constructor has parameter type "A<int> const&", so
the template is preferred. Notice that since a and b have the same type,
this is equivalent to "A<int> b(a);" except that in the "b = a" case,
explicit constructors are ignored - which we don't have here anyway.
Now since these are rather subtle criteria, i think it would be bad to give
them different user observable behaviors.
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Fri, 16 Oct 2009 09:35:26 CST Raw View
On 16 Okt., 06:15, "subramanian10...@yahoo.com, India"
<subramanian10...@yahoo.com> wrote:
> * On Oct 12, 9:24 pm, Daniel Kr gler <daniel.krueg...@googlemail.com>
> wrote:
>
>
>
> > On Oct 12, 1:05 am, "subramanian10...@yahoo.com, India"
>
> > <subramanian10...@yahoo.com> wrote:
>
> > In this case I don't see much harm, because the template constructor
>
> > template <class U> reverse_iterator(const reverse_iterator<U>& u);
>
> > does not behave completely different as a copy constructor would do.
>
> > This is important, because this c'tor will compete with the actual
> > copy
> > constructor in overload resolution situations.
>
> > HTH & Greetings from Bremen,
>
> > Daniel Kr gler
>
> > --
>
> I am unable to understand the above portion of your reply.
For understandable reasons.
> That is, when you say the template ctor will COMPETE with the actual copy ctor
> in overload resolution situation, does it mean that if both are
> provided it will result in ambiguity error ?
I used a non-standard ("slang") term here. The word compete
has no standard meaning. What I wanted to visualize here was
that both constructors participate in overload resolution.
Even though the copy-c'tor has not been user-declared in
[reverse.iterator], it is implicitly declared. Fortunately this
does not lead to an ambiguity error. Due to the language
rules, a non-template function will always be preferred over
a template function in case of a perfect argument type match,
see below. It is easier to demonstrate that in your example:
> For example, Suppose I have defined
> std::reverse_iterator<char*> rc(NULL);
>
> If both the actual ctor and the template ctor were defined and if I
> have
> std::reverse_iterator<const char*> rcc = rc;
> std::reverse_iterator<char*> temp = rc;
>
> will the last two lines result in ambiguity ? Is that what you mean by
> saying they will compete in overload resolution ?
Here is no ambiguity involved. In the second line the
argument type is a non-const lvalue of type
std::reverse_iterator<char*>,
which is a match for both the copy-c'tor and the template c'tor.
But the match for the copy c'tor is not worse than that of
the template c'tor - the considered signature would select
U = char* resulting in the same effective signature
reverse_iterator<char*>& operator=(const reverse_iterator<char*>& u);
Here the copy c'tor "wins" in overload resolution because of the
special language rule as of [over.match.best]/1:
"[..] a viable function F1 is defined to be a better function than
another
viable function F2 if for all arguments i, [..] F1 is a non-template
function
and F2 is a function template specialization[..]"
and the saying "wins" inspired me to use the non-standard
term that both "compete". In the first line the template c'tor is
chosen,
because the copy c'tor doesn't match.
HTH & Greetings from Bremen,
Daniel Kr gler
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "subramanian100in@yahoo.com, India" <subramanian100in@yahoo.com>
Date: Sun, 11 Oct 2009 17:05:00 CST Raw View
In the ISO/IEC:14882-2003 document, in page 526, in section 24.4.1.1,
the class template reverse_iterator is defined. It has the following
member template ctor which is a converting ctor.
template <class U> reverse_iterator(const reverse_iterator<U>& u);
My question: Why is this one argument ctor not declared with
'explicit' qualifier ?
Kindly explain.
Thanks
V.Subramanian
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Mon, 12 Oct 2009 10:24:37 CST Raw View
On Oct 12, 1:05 am, "subramanian10...@yahoo.com, India"
<subramanian10...@yahoo.com> wrote:
> In the ISO/IEC:14882-2003 document, in page 526, in section 24.4.1.1,
> the class template reverse_iterator is defined. It has the following
> member template ctor which is a converting ctor.
>
> template <class U> reverse_iterator(const reverse_iterator<U>& u);
>
> My question: Why is this one argument ctor not declared with
> 'explicit' qualifier ?
>
> Kindly explain.
Inverted question: Why do you believe it should be so? Basically this
is "copy-constructor"-like constructor (I emphasize: it is *not* a
copy
constructor) and should accept any reverse_iterator that wraps an
iterator type U where U can be converted to the wrapped iterator type
T
of the destination reverse_iterator, e.g. users would expect that
std::reverse_iterator<char*> rc(NULL);
std::reverse_iterator<const char*> rcc = rc;
will just work. Making the aforementioned c'tor explicit, would forbid
this
copy-initialization.
Marking constructors as explicit, requires always some thoughts about
interactions with other c'tors that would participate in overload
resolution.
In this case I don't see much harm, because the template constructor
template <class U> reverse_iterator(const reverse_iterator<U>& u);
does not behave completely different as a copy constructor would do.
This is important, because this c'tor will compete with the actual
copy
constructor in overload resolution situations.
HTH & Greetings from Bremen,
Daniel Kr gler
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]