Topic: Copy-initialization
Author: Nikolay Ivchenkov <tsoae@mail.ru>
Date: Sat, 3 Oct 2009 20:42:15 CST Raw View
C++03 - 8.5/14 contains the following wording:
Otherwise (i.e., for the remaining copy-initialization cases), user-
defined conversion sequences that can convert from the source type to
the destination type or (when a conversion function is used) to a
derived class thereof are enumerated as described in 13.3.1.4, and the
best one is chosen through overload resolution (13.3). If the
conversion cannot be done or is ambiguous, the initialization is ill-
formed. The function selected is called with the initializer
expression as its argument; if the function is a constructor, the call
initializes a temporary of the destination type. The result of the
call (which is the temporary for the constructor case) is then used to
direct-initialize, according to the rules above, the object that is
the destination of the copy-initialization.
According to this rule, the following example shall compile well:
struct X
{
X(X const *) {}
X(X &) {}
operator X const *() const { return this; }
};
int main()
{
X x = 0;
}
Direct-initialization that performs as part of copy-initialization
selects X(X const *) - its parameter is initialized by conversion
function. But VC++ 8.0 with /Za, GNU C++ 4.1.2 and Comeau-online
expect viable copy constructor. Is this bug?
Why does the standard allow extra-construction? The wording in the
rule above might be "if the function is a constructor, the call
initializes *the object that is the destination of the copy-
initialization*" - why not?
--
[ 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: Florian Weimer <fw@deneb.enyo.de>
Date: Sun, 4 Oct 2009 02:37:47 CST Raw View
* Nikolay Ivchenkov:
> According to this rule, the following example shall compile well:
>
> struct X
> {
> X(X const *) {}
> X(X &) {}
> operator X const *() const { return this; }
> };
>
> int main()
> {
> X x = 0;
> }
Are you sure? The second constructor has to be a const refence or an
rvalue reference, I think.
--
[ 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: Sun, 4 Oct 2009 09:41:20 CST Raw View
On 4 Okt., 04:42, Nikolay Ivchenkov <ts...@mail.ru> wrote:
> C++03 - 8.5/14 contains the following wording:
>
> Otherwise (i.e., for the remaining copy-initialization cases), user-
> defined conversion sequences that can convert from the source type to
> the destination type or (when a conversion function is used) to a
> derived class thereof are enumerated as described in 13.3.1.4, and the
> best one is chosen through overload resolution (13.3). If the
> conversion cannot be done or is ambiguous, the initialization is ill-
> formed. The function selected is called with the initializer
> expression as its argument; if the function is a constructor, the call
> initializes a temporary of the destination type. The result of the
> call (which is the temporary for the constructor case) is then used to
> direct-initialize, according to the rules above, the object that is
> the destination of the copy-initialization.
>
> According to this rule, the following example shall compile well:
>
> struct X
> {
> X(X const *) {}
> X(X &) {}
> operator X const *() const { return this; }
>
> };
>
> int main()
> {
> X x = 0;
>
> }
>
> Direct-initialization that performs as part of copy-initialization
> selects X(X const *) - its parameter is initialized by conversion
> function. But VC++ 8.0 with /Za, GNU C++ 4.1.2 and Comeau-online
> expect viable copy constructor. Is this bug?
>
> Why does the standard allow extra-construction? The wording in the
> rule above might be "if the function is a constructor, the call
> initializes *the object that is the destination of the copy-
> initialization*" - why not?
This is a known defect in C++03, see core issue
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#177
where it was clarified that the temporary is an rvalue, which cannot
bind to the X(X&) copy constructor.
It seems that compiler writers had already decided to interpret the
standard in this way, even though that was underspecified (We have
lvalue temporaries e.g. as part of the exception mechanism, but that
was also clarified with another issue).
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: "Johannes Schaub (litb)" <schaub-johannes@web.de>
Date: Sun, 4 Oct 2009 13:42:26 CST Raw View
Nikolay Ivchenkov wrote:
> C++03 - 8.5/14 contains the following wording:
>
> Otherwise (i.e., for the remaining copy-initialization cases), user-
> defined conversion sequences that can convert from the source type to
> the destination type or (when a conversion function is used) to a
> derived class thereof are enumerated as described in 13.3.1.4, and the
> best one is chosen through overload resolution (13.3). If the
> conversion cannot be done or is ambiguous, the initialization is ill-
> formed. The function selected is called with the initializer
> expression as its argument; if the function is a constructor, the call
> initializes a temporary of the destination type. The result of the
> call (which is the temporary for the constructor case) is then used to
> direct-initialize, according to the rules above, the object that is
> the destination of the copy-initialization.
>
> According to this rule, the following example shall compile well:
>
> struct X
> {
> X(X const *) {}
> X(X &) {}
> operator X const *() const { return this; }
> };
>
> int main()
> {
> X x = 0;
> }
>
> Direct-initialization that performs as part of copy-initialization
> selects X(X const *) - its parameter is initialized by conversion
> function. But VC++ 8.0 with /Za, GNU C++ 4.1.2 and Comeau-online
> expect viable copy constructor. Is this bug?
>
I would certainly expect that to work by only reading that description -
except when in the direct initialization pass, it doesn't consider the
conversion function. 12.3/4 contains this paragraph
> "At most one user-defined conversion (constructor or conversion function)
is implicitly applied to a single value."
If that means that an implicit conversion sequence can only contain one user
defined conversion at most, then the above code is indeed ill-formed. But
i'm a bit lost to determine what they mean with "single value". Since "X x =
0;" is an user defined conversion sequence" (see 13.3.3.1/1), the rules of
13.3.3.1.2 happen to constrain it too, and it says:
> "A user-defined conversion sequence consists of an initial standard
conversion sequence followed by a user-defined conversion (12.3) followed by
a second standard conversion sequence."
That means, either initially you convert 0 -> X, and then use the copy
constructor, or you use y -> X using a conversion function of "y" and then
use the copy constructor. The copy constructor in both cases can do either
an identity conversion or a derived->base conversion. However, in your case,
two user defined conversions would be taken, which is not compatible with a
user defined conversion sequence.
--
[ 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: Nikolay Ivchenkov <tsoae@mail.ru>
Date: Sun, 4 Oct 2009 23:55:29 CST Raw View
On 4 Oct, 23:42, "Johannes Schaub (litb)" <schaub-johan...@web.de>
wrote:
> 12.3/4 contains this paragraph
> > "At most one user-defined conversion (constructor or conversion function)
> is implicitly applied to a single value."
I can't consider this sentence as strict wording. It's unclear what
does "implicitly applied to a single value" mean. Moreover, there is
set of the rules that determines the concrete set of candidate
functions and the concrete set of viable functions for each context
within copy-initialization - these rules are defined in the subclauses
8.5 and 13.3. I consider this set of rules as primary. If any other
rule in the standard (that is not in the given set) contradicts with
consequence which is the result of applying 8.5 and 13.3 then there is
defect in the standard.
> If that means that an implicit conversion sequence can only contain one user
> defined conversion at most, then the above code is indeed ill-formed.
No. There are two unrelated implicit conversion sequences: one is the
first phase of the copy-initialization and another is the part of
direct-initialization which is the second phase of the copy-
initialization. Read 8.5/14 again:
"user-defined conversion sequences that can convert from the source
type to the destination type or (when a conversion function is used)
to a derived class thereof are enumerated as described in 13.3.1.4,
and the best one is chosen through overload resolution (13.3). If the
conversion cannot be done or is ambiguous, the initialization is ill-
formed. The function selected is called with the initializer
expression as its argument; if the function is a constructor, the call
initializes a temporary of the destination type." - these sentences
describe the first phase of the copy-initialization (for the case of
the given example).
"The result of the call (which is the temporary for the constructor
case) is then used to direct-initialize, according to the rules above,
the object that is the destination of the copy-initialization." - this
sentence describe the second phase of the copy-initialization.
So, we have two different contexts within copy-initialization where
the overload resolution is applied. In the first context (the first
phase) candidate functions are determined as follows:
" The converting constructors (12.3.1) of T are candidate functions.
When the type of the initializer expression is a class type cv S ,
the conversion functions of S and its base classes are considered.
Those that are not hidden within S and yield a type whose cv-
unqualified version is the same type as T or is a derived class
thereof are candidate functions. Conversion functions that return
reference to X return lvalues of type X and are therefore considered
to yield X for this process of selecting candidate functions." (see
13.3.1.4/1)
There are two candidate functions in this case: X(X const *) and X(X
&). But only X(X const *) is viable, so it is selected by overload
resolution.
In the second context (the second phase - direct-initialization)
candidate functions are determined as follows:
"For direct-initialization, the candidate functions are all the
constructors of the class of the object being initialized." (see
13.3.1.3).
There are two candidate functions in this case: X(X const *) and X(X
&). Suppose X(X &) is not viable (because the first phase produces
rvalue). Consider X(X const *). 13.3.2/2 states: "First, to be a
viable function, a candidate function shall have enough parameters to
agree in number with the
arguments in the list". X(X const *) satisfies these conditions.
13.3.2/3 states: "Second, for F to be a viable function, there shall
exist for each argument an implicit conversion sequence (13.3.3.1)
that converts that argument to the corresponding parameter of F".
There is the implicit conversion sequence that converts rvalue of type
X to type X const * - it is user-defined conversion sequence that
invokes conversion function X::operator X const *() const. So, X(const
*) is viable function and it is selected by the overload resolution.
According to 8.5/14 such direct-initialization (which is part of copy-
initialization) shall be performed in the same manner as in the
following example:
struct X
{
X(X const *) {}
X(X &) {}
operator X const *() const { return this; }
};
int main()
{
X x(X(0));
}
--
[ 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, 5 Oct 2009 12:13:13 CST Raw View
On Oct 5, 7:55 am, Nikolay Ivchenkov <ts...@mail.ru> wrote:
> On 4 Oct, 23:42, "Johannes Schaub (litb)" <schaub-johan...@web.de>
> wrote:
>
> > 12.3/4 contains this paragraph
> > > "At most one user-defined conversion (constructor or conversion function)
> > is implicitly applied to a single value."
>
> I can't consider this sentence as strict wording. It's unclear what
> does "implicitly applied to a single value" mean. Moreover, there is
> set of the rules that determines the concrete set of candidate
> functions and the concrete set of viable functions for each context
> within copy-initialization - these rules are defined in the subclauses
> 8.5 and 13.3. I consider this set of rules as primary. If any other
> rule in the standard (that is not in the given set) contradicts with
> consequence which is the result of applying 8.5 and 13.3 then there is
> defect in the standard.
13.3 mentions further restrictions, see below.
> > If that means that an implicit conversion sequence can only contain one user
> > defined conversion at most, then the above code is indeed ill-formed.
>
> No. There are two unrelated implicit conversion sequences: one is the
> first phase of the copy-initialization and another is the part of
> direct-initialization which is the second phase of the copy-
> initialization. Read 8.5/14 again:
>
> "user-defined conversion sequences that can convert from the source
> type to the destination type or (when a conversion function is used)
> to a derived class thereof are enumerated as described in 13.3.1.4,
> and the best one is chosen through overload resolution (13.3). If the
> conversion cannot be done or is ambiguous, the initialization is ill-
> formed. The function selected is called with the initializer
> expression as its argument; if the function is a constructor, the call
> initializes a temporary of the destination type." - these sentences
> describe the first phase of the copy-initialization (for the case of
> the given example).
>
> "The result of the call (which is the temporary for the constructor
> case) is then used to direct-initialize, according to the rules above,
> the object that is the destination of the copy-initialization." - this
> sentence describe the second phase of the copy-initialization.
>
> So, we have two different contexts within copy-initialization where
> the overload resolution is applied. In the first context (the first
> phase) candidate functions are determined as follows:
>
> " The converting constructors (12.3.1) of T are candidate functions.
> When the type of the initializer expression is a class type cv S ,
> the conversion functions of S and its base classes are considered.
> Those that are not hidden within S and yield a type whose cv-
> unqualified version is the same type as T or is a derived class
> thereof are candidate functions. Conversion functions that return
> reference to X return lvalues of type X and are therefore considered
> to yield X for this process of selecting candidate functions." (see
> 13.3.1.4/1)
>
> There are two candidate functions in this case: X(X const *) and X(X
> &). But only X(X const *) is viable, so it is selected by overload
> resolution.
>
> In the second context (the second phase - direct-initialization)
> candidate functions are determined as follows:
>
> "For direct-initialization, the candidate functions are all the
> constructors of the class of the object being initialized." (see
> 13.3.1.3).
>
> There are two candidate functions in this case: X(X const *) and X(X
> &). Suppose X(X &) is not viable (because the first phase produces
> rvalue). Consider X(X const *). 13.3.2/2 states: "First, to be a
> viable function, a candidate function shall have enough parameters to
> agree in number with the
> arguments in the list". X(X const *) satisfies these conditions.
> 13.3.2/3 states: "Second, for F to be a viable function, there shall
> exist for each argument an implicit conversion sequence (13.3.3.1)
> that converts that argument to the corresponding parameter of F".
> There is the implicit conversion sequence that converts rvalue of type
> X to type X const * - it is user-defined conversion sequence that
> invokes conversion function X::operator X const *() const. So, X(const
> *) is viable function and it is selected by the overload resolution.
>
> According to 8.5/14 such direct-initialization (which is part of copy-
> initialization) shall be performed in the same manner as in the
> following example:
>
> struct X
> {
> X(X const *) {}
> X(X &) {}
> operator X const *() const { return this; }
> };
>
> int main()
> {
> X x(X(0));
> }
I was a bit quick with my first reply and stopped when I saw
the rvalue issue, sorry for that.
Nevertheless I believe that your conclusions are not correct,
because the standard explicitly says in [over.best.ics]/4:
"However, when considering the argument of a user-defined
conversion function that is a candidate by 13.3.1.3 when
invoked for the copying of the temporary in the second step
of a class copy-initialization, or by 13.3.1.4, 13.3.1.5, or
13.3.1.6 in all cases, only standard conversion sequences
and ellipsis conversion sequences are allowed."
This excludes the consideration of another user-defined
conversion during initialization. I agree that the standard
could be clearer here and a reference to this clause from
13.3.1.4 to 13.3.3.1
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: "Johannes Schaub (litb)" <schaub-johannes@web.de>
Date: Mon, 5 Oct 2009 12:14:25 CST Raw View
Nikolay Ivchenkov wrote:
> On 4 Oct, 23:42, "Johannes Schaub (litb)" <schaub-johan...@web.de>
> wrote:
>> If that means that an implicit conversion sequence can only contain one
>> user defined conversion at most, then the above code is indeed
>> ill-formed.
>
> No. There are two unrelated implicit conversion sequences: one is the
> first phase of the copy-initialization and another is the part of
> direct-initialization which is the second phase of the copy-
> initialization. Read 8.5/14 again:
>
> "user-defined conversion sequences that can convert from the source
> type to the destination type or (when a conversion function is used)
> to a derived class thereof are enumerated as described in 13.3.1.4,
> and the best one is chosen through overload resolution (13.3). If the
> conversion cannot be done or is ambiguous, the initialization is ill-
> formed. The function selected is called with the initializer
> expression as its argument; if the function is a constructor, the call
> initializes a temporary of the destination type." - these sentences
> describe the first phase of the copy-initialization (for the case of
> the given example).
>
> "The result of the call (which is the temporary for the constructor
> case) is then used to direct-initialize, according to the rules above,
> the object that is the destination of the copy-initialization." - this
> sentence describe the second phase of the copy-initialization.
>
> So, we have two different contexts within copy-initialization where
> the overload resolution is applied. In the first context (the first
> phase) candidate functions are determined as follows:
>
> " The converting constructors (12.3.1) of T are candidate functions.
> When the type of the initializer expression is a class type cv S ,
> the conversion functions of S and its base classes are considered.
> Those that are not hidden within S and yield a type whose cv-
> unqualified version is the same type as T or is a derived class
> thereof are candidate functions. Conversion functions that return
> reference to X return lvalues of type X and are therefore considered
> to yield X for this process of selecting candidate functions." (see
> 13.3.1.4/1)
>
> There are two candidate functions in this case: X(X const *) and X(X
> &). But only X(X const *) is viable, so it is selected by overload
> resolution.
>
> In the second context (the second phase - direct-initialization)
> candidate functions are determined as follows:
>
While reading http://www.open-
std.org/jtc1/sc22/wg21/docs/cwg_active.html#670 i found another paragraph
that unambiguously clearifies it, i think:
> "However, when considering the argument of a user-defined conversion
function that is a candidate by 13.3.1.3 when invoked for the copying of the
temporary in the second step of a class copy-initialization, or by 13.3.1.4,
13.3.1.5, or 13.3.1.6 in all cases, only standard conversion sequences and
ellipsis conversion sequences are allowed."
The allowing of ellipsis conversion sequences is interesting. It seems like
you are right, and we have to do with two completely independent conversion
sequences, and this paragraph is required to forbid further user defined
conversions from happening.
I think i understood this now: Description of copy initialization makes use
of a nested user defined conversion sequence, and user defined conversion
sequences have a second standard conversion sequence that can already do a
derived->base conversion if possible by a standard conversion sequence. One
thing i'm unclear about though:
struct Z;
struct X { operator Z(); };
struct Y { Y(...); Y(Y&); };
struct Z : Y { };
Y y = X();
I wonder whether in this example, the result of "operator Z" can be
converted to Y by using "Y(...)". Since this would seem to be a derived-
>base conversion, it would be a standard conversion sequence. But on the
other side, it would use an ellipsis conversion during conversion of the
argument. Do you have an idea whether this would be allowed as the second
standard conversion sequence? If yes, then i think we can always end up with
a type equal with the destination type with copy initialization, i think,
without doing the following direct initialization.
In any case, I agree with you that your original example would be well
formed, since it in fact would do an independent direct initialization. By
the paragraph 13.3.3.1/4, however, that one can only do ellipsis conversion
sequences or standard conversion sequences, which will mark the original
example ill formed. Now it also makes sense to me that 13.3.3.1/6 contains
the following note
> "[Note: when the parameter has a class type, this is a conceptual
conversion defined for the purposes of clause 13; the actual initialization
is defined in terms of constructors and is not a conversion. ]"
I think that's the solution - in case of class types, user defined
conversion sequences are not exactly identical with copy initialization. And
i've learned something new again :)
--
[ 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: Mon, 5 Oct 2009 12:15:06 CST Raw View
Nikolay Ivchenkov wrote:
> On 4 Oct, 23:42, "Johannes Schaub (litb)" <schaub-johan...@web.de>
> wrote:
>> 12.3/4 contains this paragraph
>> > "At most one user-defined conversion (constructor or conversion
>> > function)
>> is implicitly applied to a single value."
>
> I can't consider this sentence as strict wording. It's unclear what
> does "implicitly applied to a single value" mean.
>
I completely agree with you, i've done a poor quote. :)
>
>> If that means that an implicit conversion sequence can only contain one
>> user defined conversion at most, then the above code is indeed
>> ill-formed.
>
> No. There are two unrelated implicit conversion sequences: one is the
> first phase of the copy-initialization and another is the part of
> direct-initialization which is the second phase of the copy-
> initialization. Read 8.5/14 again:
>
> ...
>
> In the second context (the second phase - direct-initialization)
> candidate functions are determined as follows:
>
> "For direct-initialization, the candidate functions are all the
> constructors of the class of the object being initialized." (see
> 13.3.1.3).
>
> There are two candidate functions in this case: X(X const *) and X(X
> &). Suppose X(X &) is not viable (because the first phase produces
> rvalue). Consider X(X const *). 13.3.2/2 states: "First, to be a
> viable function, a candidate function shall have enough parameters to
> agree in number with the
> arguments in the list". X(X const *) satisfies these conditions.
> 13.3.2/3 states: "Second, for F to be a viable function, there shall
> exist for each argument an implicit conversion sequence (13.3.3.1)
> that converts that argument to the corresponding parameter of F".
> There is the implicit conversion sequence that converts rvalue of type
> X to type X const * - it is user-defined conversion sequence that
> invokes conversion function X::operator X const *() const. So, X(const
> *) is viable function and it is selected by the overload resolution.
>
> According to 8.5/14 such direct-initialization (which is part of copy-
> initialization) shall be performed in the same manner as in the
> following example:
>
> struct X
> {
> X(X const *) {}
> X(X &) {}
> operator X const *() const { return this; }
> };
>
> int main()
> {
> X x(X(0));
> }
>
All this should be seen as being constrained by 4/3. I have long not
understood what 13.3.3.1/1 means with the following, which i now regard as
being one of the most important paragraphs:
> "An implicit conversion sequence is a sequence of conversions used to
convert an argument in a function call to the type of the corresponding
parameter of the function being called. The sequence of conversions is an
implicit conversion as defined in clause 4, which means it is governed by
the rules for initialization of an object or reference by a single
expression (8.5, 8.5.3)."
But i've recently understood that all it says is that the implicit
conversion sequences it describes in length in 13.3.3.1 about overload
resolution applies in its entirety to "T t = e;" - i.e it describes how copy
intialization in general is valid, and what it describes there is just copy
initialization. Argument passing uses copy initialization according to
8.5/12, and this i think is the key point in understanding all this.
Of course, that the second, direct initialization, is restricted to only
standard conversions, can also be seen by considering how only conversion
functions that return T or types derived from T are considered in the first
phase :) If it werent for this, all conversion functions would be
considered, i think, and it could return types that can be converted by
converting constructors in the second phase - but it's not so.
Only here, we can end up with only doing a standard conversion sequence:
both identity conversions (T -> T) and derived-to-base conversions (U -> T)
are standard conversion sequences (of course as you teached me recently,
they aren't standard conversions, but they are conversion sequences
introduced in 13.3.3.1 ;)).
I don't think this semantics are obvious, but this is why the
implementations reject that code, i think.
--
[ 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: Nikolay Ivchenkov <tsoae@mail.ru>
Date: Mon, 5 Oct 2009 14:13:39 CST Raw View
On 5 Oct, 22:13, Daniel Kr gler <daniel.krueg...@googlemail.com>
wrote:
>
> Nevertheless I believe that your conclusions are not correct,
> because the standard explicitly says in [over.best.ics]/4:
>
> "However, when considering the argument of a user-defined
> conversion function that is a candidate by 13.3.1.3 when
> invoked for the copying of the temporary in the second step
> of a class copy-initialization, or by 13.3.1.4, 13.3.1.5, or
> 13.3.1.6 in all cases, only standard conversion sequences
> and ellipsis conversion sequences are allowed."
>
> This excludes the consideration of another user-defined
> conversion during initialization. I agree that the standard
> could be clearer here and a reference to this clause from
> 13.3.1.4 to 13.3.3.1
Thanks for this note. I didn't consider this sentence because of
"conversion function" presence :-) The term "conversion function" is
defined in 12.3.2, it doesn't mean a constructor. Properly changed
sentence (like "However, when considering the argument of *<a
function>* that is a candidate by 13.3.1.3 when invoked for the
copying of the temporary in the second step of a class copy-
initialization, or by 13.3.1.4, 13.3.1.5, or 13.3.1.6 in all cases,
only standard conversion sequences and ellipsis conversion sequences
are *<considered (in particular, for the purposes of determining
whether the candidate function (that is either a constructor or a
conversion function) is viable)>*.") can solve my question #1.
But what can you say about the second question: why the extra-
construction is specified for copy-initialization?
--
[ 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: tohava <tohava@gmail.com>
Date: Tue, 6 Oct 2009 12:58:08 CST Raw View
On Oct 5, 10:13 pm, Nikolay Ivchenkov <ts...@mail.ru> wrote:
> only standard conversion sequences and ellipsis conversion sequences
> are *<considered (in particular, for the purposes of determining
> whether the candidate function (that is either a constructor or a
> conversion function) is viable)>*.") can solve my question #1.
What is the rational behind this decision?
--
[ 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: Wed, 7 Oct 2009 14:08:08 CST Raw View
tohava wrote:
> On Oct 5, 10:13 pm, Nikolay Ivchenkov <ts...@mail.ru> wrote:
>> only standard conversion sequences and ellipsis conversion sequences
>> are *<considered (in particular, for the purposes of determining
>> whether the candidate function (that is either a constructor or a
>> conversion function) is viable)>*.") can solve my question #1.
>
> What is the rational behind this decision?
>
>
This was a change introduced in this paper: http://www.open-
std.org/jtc1/sc22/wg21/docs/papers/2000/n1232.pdf , to disallow some
undesired auto_ptr conversions.
--
[ 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: Nikolay Ivchenkov <tsoae@mail.ru>
Date: Fri, 9 Oct 2009 16:52:22 CST Raw View
On 6 Oct, 22:58, tohava <toh...@gmail.com> wrote:
> On Oct 5, 10:13 pm, Nikolay Ivchenkov <ts...@mail.ru> wrote:
>
> > only standard conversion sequences and ellipsis conversion sequences
> > are *<considered (in particular, for the purposes of determining
> > whether the candidate function (that is either a constructor or a
> > conversion function) is viable)>*.") can solve my question #1.
>
> What is the rational behind this decision?
Did you mean the proposed change? Consider the example below:
struct X
{
X(X const *);
X(X &);
X(...);
operator X const *() const;
};
int f(X);
int main()
{
sizeof f(0);
}
I see two possible interpretations of "allowed" in the aforementioned
sentece:
1) "considered at all" - in this case the code above is well-formed,
because X(X const *) is not viable, but X(...) is viable, and X(...)
is selected by the overload resolution;
2) "considered as valid after the overload resolution is done" - in
this case the code above is ill-formed, because X(X const *) is still
viable, and it is selected by the overload resolution, but the
conversion it invokes is ill-formed (not allowed).
Which interpretation is right, and how to prove the answer? IMO, the
first variant is more intuitive.
--
[ 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 ]