Topic: explicit and conversion during return
Author: jpotter@falcon.lhup.edu (John Potter)
Date: 1999/08/04 Raw View
On 02 Aug 99 05:21:47 GMT, sbnaran@localhost.localdomain (Siemel Naran)
wrote:
: On 1 Aug 1999 15:51:41 GMT, John Potter <jpotter@falcon.lhup.edu> wrote:
:
: >If explicit is meaningless on a copy ctor, I'm sure nobody will want
: >one ;-)
:
: Well, I read Francis' suggestion that the explicit specifier on the
: copy constructor prevents implicit calls to the copy constructor, as
: in pass and return by value.
But, that is the question. I don't think that it has been answered.
: So then, the explicit specifier can possibly serve one purpose:
: prevent pass and return by value. But why would one want to do
: this anyway?
Design decision. Copying is expensive and should not be done by
accident. Pass by value can be simulated by taking a reference
and using it to copy initialize a local variable. Return by value
can be simulated by passing a reference to a local variable in the
calling function. If the client really wants to copy an object, it
can be done.
Back to the real question. What is the effect of using the explicit
key word on a copy ctor?
Section 12.3.1. /2 says that an explicit ctor may only be used with
direct initialization syntax or cast. It also says that a default ctor
may be explicit but will still be used for default initialization. I
have no problem with that because X x; is direct initialization syntax.
For an explicit copy ctor, it would seem to say that X x = X(); is
invalid because it uses copy initialization syntax. However, the
semantics is direct initialization of x using the copy ctor.
/3 says that a copy ctor is a converting ctor and that a non-explicit
copy ctor may be called for implicit type conversions.
Can anyone provide an example of an implicit type conversion using a
copy ctor?
Possible conclusions to date:
1. Egcs has a bug.
It does not use an explicit copy ctor for pass by value.
2. EDG has a bug.
It uses an explicit copy ctor for pass by value.
3. The standard has a bug.
Two respected compilers disagree.
4. We have a bug.
We can not use the standard to show which of 1 and 2 is correct.
These are obviously not mutually exclusive.
John
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/08/04 Raw View
In article <37a5f24f.19906381@news.csrlink.net>, John Potter
<jpotter@falcon.lhup.edu> writes
>/3 says that a copy ctor is a converting ctor and that a non-explicit
>copy ctor may be called for implicit type conversions.
is slicing not a type conversion?
Francis Glassborow Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: 1999/08/04 Raw View
On 4 Aug 1999 19:02:54 GMT, Francis Glassborow
<francis@robinton.demon.co.uk> wrote:
: In article <37a5f24f.19906381@news.csrlink.net>, John Potter
: <jpotter@falcon.lhup.edu> writes
: >/3 says that a copy ctor is a converting ctor and that a non-explicit
: >copy ctor may be called for implicit type conversions.
:
: is slicing not a type conversion?
You're asking me? I asked if slicing was a type conversion the other
day and nobody answered. You started this by saying that the meaning
of explicit for a copy ctor needed clearification. We are proving that
we don't know what we are talking about, aren't we? ;-)
We could take Bonnard's word that explicit has no meaning for a copy
ctor and drop the subject. However, the above standard statement seems
to say that it does mean something. Is there a language lawyer out
there willing to explain it?
Lacking that, here is an opinion from BC++5 which seems to make
commonsense, more or less.
struct S {
S () { }
explicit S (S const&) { }
};
struct D : S {
};
D d;
S s1(d); // ok direct syntax
S s3 = s1; // ok copy syntax, direct semantics ???
S s2 = d; // error copy syntax, direct semantics, conversion ???
void f (S) { }
void g () {
f(s1); // ok copy syntax, direct semantics ???
f(d); // error copy syntax, direct semantics, conversion ???
}
It is consistent. Copy syntax without conversion is accepted while
copy syntax with slicing is rejected. Is that what the standard
says?
Note that egcs rejects all copy syntax which also makes sense.
Siemel, could you provide your EDG based compiler opinion for the above?
Any others? This is not right, but it does give the opinion of some
compilers which should have some language lawyers behind them.
If BC++, EDG, and the standard agree, a use is prevention of accidental
slicing in some cases. It does not prevent slicing by the usual copy
assignment. If explicit means anything on a copy ctor there may a use
for it. Otherwise, it is just one of those things which is allowed to
make the grammer easier.
John
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/08/05 Raw View
In article <37a5f24f.19906381@news.csrlink.net>, John Potter
<jpotter@falcon.lhup.edu> writes
>We can not use the standard to show which of 1 and 2 is correct.
>
>These are obviously not mutually exclusive.
So has a DR been raised? Sorry, I'm feeling lazy and do not want to go
and hunt through the current issue's lists.
Francis Glassborow Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: stanley@West.Sun.COM (Stanley Friesen [Contractor])
Date: 1999/08/05 Raw View
In article <37a5f24f.19906381@news.csrlink.net>,
John Potter <jpotter@falcon.lhup.edu> wrote:
>
>Can anyone provide an example of an implicit type conversion using a
>copy ctor?
Sure.
class B {
B(const B &b) { /* do stuff */ };
};
class D: public B {
...
};
func(B myb)
{
// do stuff
}
otherfunc()
{
D myd;
func(myd); // uses B's copy constructor to convert D to B
// probably not a great idea, bu that is what it does
}
Based on this example, I would say that an explicit copy constructor had
*better* be forbidden for pass by value.
>1. Egcs has a bug.
>It does not use an explicit copy ctor for pass by value.
This should be the *desired* result, given my example.
>
>4. We have a bug.
>We can not use the standard to show which of 1 and 2 is correct.
Apparently.
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: 1999/08/06 Raw View
On 5 Aug 1999 18:28:18 GMT, stanley@West.Sun.COM (Stanley Friesen
[Contractor]) wrote:
:
: In article <37a5f24f.19906381@news.csrlink.net>,
: John Potter <jpotter@falcon.lhup.edu> wrote:
: >
: >Can anyone provide an example of an implicit type conversion using a
: >copy ctor?
:
: Sure.
:
: class B {
: B(const B &b) { /* do stuff */ };
: };
:
: class D: public B {
: ...
: };
:
: func(B myb)
: {
: // do stuff
: }
:
: otherfunc()
: {
: D myd;
:
: func(myd); // uses B's copy constructor to convert D to B
: // probably not a great idea, bu that is what it does
Since this is copy syntax, it would use B::B(const B&) to form a
temporary B by slicing myd and then use B::B(const B&) to initialize
myb. I think that the first should be disallowed but the second
should be allowed. Unfortunately, the standard says that when the
source is the same as the destination or derived from it, the
semantics are the same as direct initialization and there is only
one ctor used. It is still a conversion.
func(B(myd));
should be valid with an explicit copy ctor because there is no
implicit conversion.
: }
:
:
: Based on this example, I would say that an explicit copy constructor had
: *better* be forbidden for pass by value.
:
: >1. Egcs has a bug.
: >It does not use an explicit copy ctor for pass by value.
:
: This should be the *desired* result, given my example.
I don't think so. It will not accept the second form above nor even
passing a B.
: >
: >4. We have a bug.
: >We can not use the standard to show which of 1 and 2 is correct.
:
: Apparently.
At this point, I am ready to accept 1, reject 2 and 3, and debug 4.
The section of the standard involved is talking about conversion
constructors. A copy constructor is a conversion constructor but
not all uses of it involve conversions. An explicit copy ctor
may not be used for implicit conversions (slicing); however, it may
be used for explicit conversions and copying.
I am satisfied with BC++5, EDG if it rejects implicit slicing, the
standard, and myself for finally being able to make sense out of this
part of the standard. If egcs 2.95 still rejects all copy syntax
copies, a bug report should be submitted.
Objections?
John
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/08/07 Raw View
In article <37aa10e4.30460801@news.csrlink.net>, John Potter
<jpotter@falcon.lhup.edu> writes
>The section of the standard involved is talking about conversion
>constructors. A copy constructor is a conversion constructor but
>not all uses of it involve conversions. An explicit copy ctor
>may not be used for implicit conversions (slicing); however, it may
>be used for explicit conversions and copying.
I thought that T and (T const) were different types with a trivial
conversion from T to (T const). Most copy ctors actually provide a
conversion from (T const) to T.
strictly speaking I think:
void fn(mytype);
int main() {
mytype mt;
mytype const mtc;
fn(mt); // no conversion source and destination same type
fn(mtc); // conversion from (mytype const) to mytype.
And remember that you are allowed to have distinct copy ctors for the
different cv-qualified (sub-)types
OK, I think I am nit-picking but getting the wording right is not always
easy.
>
>I am satisfied with BC++5, EDG if it rejects implicit slicing, the
>standard, and myself for finally being able to make sense out of this
>part of the standard. If egcs 2.95 still rejects all copy syntax
>copies, a bug report should be submitted.
I would be happy with this as it adds some utility (the ability to
prohibit implicit slicing) while allowing copying.
>
>Objections?
Francis Glassborow Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: 1999/08/01 Raw View
On 31 Jul 99 16:15:02 GMT, sbnaran@localhost.localdomain (Siemel Naran)
wrote:
[ egcs will not pass by value with explicit copy ctor, an EDG will. ]
: If you want an explicit copy constructor, would this work? A
: static function 'X X::copy(const X&)' or a member function
: 'X X::copy()', and the real copy constructor private? Consider:
: X x2=x1.copy();
: This requires X::X(const X&) to put the return of x1.copy() into
: x2, even though a good compiler will create the return of x1.copy()
: in x2.
Did you try this one? The = form and X x2(x1.copy()) both require an
accessable copy ctor.
I don't think anyone wants an explicit copy ctor. The question is
what does it mean. The standard allows it and makes a point of
saying that the generated copy ctor is not explicit. The standard
also allows any ctor to be explicit. It seems that explicit is
meaningless on a default ctor and any ctor with more than one
required parameter. We know what it means for one parameter ctors
with the exception of the copy ctors.
How about this one?
struct B {
B ();
explicit B (B const&);
};
struct D : B {
};
void f (B);
void g () {
d;
f(d);
}
Is that an implicit slicing call or just a standard reference
conversion to an explicit copy? What does EDG say?
If explicit is meaningless on a copy ctor, I'm sure nobody will want
one ;-)
John
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: sbnaran@localhost.localdomain (Siemel Naran)
Date: 1999/08/02 Raw View
On 1 Aug 1999 15:51:41 GMT, John Potter <jpotter@falcon.lhup.edu> wrote:
>Did you try this one? The = form and X x2(x1.copy()) both require an
>accessable copy ctor.
>If explicit is meaningless on a copy ctor, I'm sure nobody will want
>one ;-)
Well, I read Francis' suggestion that the explicit specifier on the
copy constructor prevents implicit calls to the copy constructor, as
in pass and return by value. At first, this struck me as too subtle.
I thought that if one really wanted an explicit copy constructor,
one should make a function like X::copy() const and make the real
copy constructor private and implemented. Then one could say stuff
like this:
X x2=x1.copy();
f(x1.copy());
return x1.copy();
However, I realize now that all of these forms require the real
copy constructor X::X(const X&) to be accessible, although the
constructor will likely not be used on a sufficiently optimizing
compiler (eg, egcs). So the X::copy() const idea is not a
substitute for an explicit copy constructor.
So then, the explicit specifier can possibly serve one purpose:
prevent pass and return by value. But why would one want to do
this anyway?
--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/08/02 Raw View
In article <slrn7q9fhl.9hq.sbnaran@localhost.localdomain>, Siemel Naran
<sbnaran@localhost.localdomain> writes
>So then, the explicit specifier can possibly serve one purpose:
>prevent pass and return by value. But why would one want to do
>this anyway?
Well why do people make a copy ctor private and then provide a clone
function? Anyway I am not greatly fussed, I just like taking out these
corner issues and seeing if they have anything to offer.
Francis Glassborow Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: 1999/07/25 Raw View
On 24 Jul 99 22:09:45 GMT, Francis Glassborow
<francis@robinton.demon.co.uk> wrote:
: In article <37980270.55870003@news.csrlink.net>, John Potter
: <jpotter@falcon.lhup.edu> writes
: I guess that I will
: >need to get used to (static) casting my returns. That may be good.
: Nonsense, just get used to writing function style initialisations.
Not nonsense, the subject is return not variable declaration. I use
the direct initialization form for declarations. I remember when I
could not use "int x(5);" and did not like it.
I'm sure that you know that what appears to be a pseudo constructor
call with a single parameter is really a function style cast which
is treated as a static_cast.
struct X { explicit X (int); };
X x1(42); // valid
X x2 = 42; // invalid
X x3 = X(42); // Be explicit by using a static_cast.
I think the second line was very _explicit_, but I don't use it.
X f2 () { return 42; } // invalid
X f3 () { return X(42); } // Be explicit by using a static_cast.
I think the first line was very _explicit_, and I do use it. I guess
that I should change my ways.
void g (X); // or (X const&)
g(42); // invalid
g(X(42)); // Be explicit by using a static_cast.
I think that this was the real reason for explicit with operator=
being the most likely function. The pre-explicit hack of using an
intermediate conversion class had the same results in all three
cases.
To be honest, the only example that I remember is
vector<int> v(10);
v = 42; // oops I meant v[5] = 42;
No complaints. I don't think that there are any surprises for the
first two cases, but the need to cover the third case and the language
definition produced the side effect of including the first two cases.
No big deal. I just stated that I don't think explicit was intended
to prevent the conversion in a return statement. It just happened
as a side effect of the real intent.
Counter example(s) appreciated, I'm always open to education.
John
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/07/26 Raw View
In article <slrn7pagsn.atn.sbnaran@localhost.localdomain>, Siemel Naran
<sbnaran@localhost.localdomain> writes
>> int main ()
>> {
>> X x = f ();
>>
>> return 0;
>> };
>
>Indeed, this is ill-formed.
but
int main() {
X x(f());
return 0;
}
is OK, I think. In my experience you get fewer surprises by using
function style initialisation.
Francis Glassborow Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/07/26 Raw View
In article <379a7517.4301000@news.csrlink.net>, John Potter
<jpotter@falcon.lhup.edu> writes
>struct X { explicit X (int); };
>
>X x1(42); // valid
>X x2 = 42; // invalid
>X x3 = X(42); // Be explicit by using a static_cast.
I think this is a matter of viewpoint. The ctor and dtor are called.
Functionally it is a static_cast but the mechanism is via ctor/dtor
calls.
>
>I think the second line was very _explicit_, but I don't use it.
>
>X f2 () { return 42; } // invalid
>X f3 () { return X(42); } // Be explicit by using a static_cast.
As the author of the return statement is also the author of the return
type I agree that this is seems like an over-requirement.
>
>I think the first line was very _explicit_, and I do use it. I guess
>that I should change my ways.
>
>void g (X); // or (X const&)
>g(42); // invalid
>g(X(42)); // Be explicit by using a static_cast.
OTOH I feel quite comfortable with it being required here as it makes
the programmer recognise that a temporary is involved.
However there is a point that I think needs addressing and that is what
happens if the programmer qualifies the copy ctor as explicit?
Francis Glassborow Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: 1999/07/27 Raw View
On 26 Jul 1999 16:48:41 GMT, Francis Glassborow
<francis@robinton.demon.co.uk> wrote:
: In article <379a7517.4301000@news.csrlink.net>, John Potter
: <jpotter@falcon.lhup.edu> writes
: >void g (X); // or (X const&)
: >g(42); // invalid
: >g(X(42)); // Be explicit by using a static_cast.
:
: OTOH I feel quite comfortable with it being required here as it makes
: the programmer recognise that a temporary is involved.
Agreed, this is the one we want. The others come with it because of
the way the language is defined.
: However there is a point that I think needs addressing and that is what
: happens if the programmer qualifies the copy ctor as explicit?
Let's assume that there is only that one copy ctor.
It seems obvious that it disables anything equivalent to
X x =
which means there is also no pass or return by value. Egcs agrees.
What about an explicit default constructor? It seems that it
would disable variables without initializers and members without
mention in constructor initializer list. I can't find anything
that egcs disallows.
John
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/07/27 Raw View
In article <379cd62b.49206010@news.csrlink.net>, John Potter
<jpotter@falcon.lhup.edu> writes
>Let's assume that there is only that one copy ctor.
>
>It seems obvious that it disables anything equivalent to
> X x =
>which means there is also no pass or return by value. Egcs agrees.
>
>What about an explicit default constructor? It seems that it
>would disable variables without initializers and members without
>mention in constructor initializer list. I can't find anything
>that egcs disallows.
However it allows explicit creation of a temporary that can be bound to
a reference. Hm... I wonder if that might be useful.
Francis Glassborow Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: 1999/07/27 Raw View
On 26 Jul 99 14:52:53 GMT, Francis Glassborow
<francis@robinton.demon.co.uk> wrote:
: In article <slrn7pagsn.atn.sbnaran@localhost.localdomain>, Siemel Naran
: <sbnaran@localhost.localdomain> writes
: >> int main ()
: >> {
: >> X x = f ();
: >>
: >> return 0;
: >> };
: >
: >Indeed, this is ill-formed.
:
: but
:
: int main() {
: X x(f());
: return 0;
: }
:
: is OK, I think.
Nope, you missed the whole point, please see the Subject:. There is
nothing wrong with main. Since f returns an X, the two forms have
identical semantics.
> X f ()
> {
> int i = 42;
> return i;
> }
The return statement in f is the problem. The return requires a
conversion and the constructor is explicit. The return must be
return X(i); // return static_cast<X>(i);
John
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: sbnaran@localhost.localdomain (Siemel Naran)
Date: 1999/07/31 Raw View
On 28 Jul 1999 19:02:41 GMT, Francis Glassborow
>In article <379E459F.763F@wanadoo.fr>, Valentin Bonnard
>>It doesn't make any sens to do so. I think it has no effect.
>It prevents pass/return by value while allowing explicit creation of
>copies. Somewhat similar to a private copy ctor with a static method to
>allow cloning.
I'm not sure that the 'explicit' specifier on the copy constructor has
any effect. Anyway, consider this program:
struct X {
X();
explicit X(const X&);
};
void f(X);
int main() { X x; f(x); }
Egcs refuses to compile the program on the grounds that there is no
way to copy 'x'. If I remove the 'explicit', then the program of
course compiles. But this does not mean that egcs is right.
My EDG compiler does indeed compile the code. That is, it ignores
the 'explicit' specifier on the copy constructor. But this does
not mean that the EDG compiler is right.
If you want an explicit copy constructor, would this work? A
static function 'X X::copy(const X&)' or a member function
'X X::copy()', and the real copy constructor private? Consider:
X x2=x1.copy();
This requires X::X(const X&) to put the return of x1.copy() into
x2, even though a good compiler will create the return of x1.copy()
in x2.
--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: 1999/07/31 Raw View
On 28 Jul 99 07:23:35 GMT, Francis Glassborow
<francis@robinton.demon.co.uk> wrote:
: In article <379caaee.38135270@news.csrlink.net>, John Potter
: <jpotter@falcon.lhup.edu> writes
: >Nope, you missed the whole point, please see the Subject:. There is
: >nothing wrong with main. Since f returns an X, the two forms have
: >identical semantics.
:
: I may have missed the point but the semantics of the two forms are not
: identical.
See 8.5/14 second sub bullet of fourth bullet: direct initialization
or copy initialization where the source has the same type ...
One paragraph covers both.
: The assignment version requires an accessible non explicit
: copy ctor whilst the function form does not.
The assignment version is copy initialization using the copy ctor only,
there is no temporary. The function form is direct initialization using
the copy ctor. They both require an accessible copy ctor.
An explicit copy ctor is a can of worms. It no longer seems obvious
when a use of a copy ctor is implicit or explicit. I could argue that
writing the = explicitly calls for use of the copy ctor. It could be
argued that the copy ctor is implicitely required by the form of the
expression. I give up. Could someone explain? Given an explanation,
does anyone see a practical use for such an animal?
John
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/07/28 Raw View
In article <379caaee.38135270@news.csrlink.net>, John Potter
<jpotter@falcon.lhup.edu> writes
>Nope, you missed the whole point, please see the Subject:. There is
>nothing wrong with main. Since f returns an X, the two forms have
>identical semantics.
I may have missed the point but the semantics of the two forms are not
identical. The assignment version requires an accessible non explicit
copy ctor whilst the function form does not.
Francis Glassborow Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: 1999/07/28 Raw View
On 27 Jul 99 10:29:00 GMT, Francis Glassborow
<francis@robinton.demon.co.uk> wrote:
: In article <379cd62b.49206010@news.csrlink.net>, John Potter
: <jpotter@falcon.lhup.edu> writes
I assume we agree on the explicit copy ctor.
: >What about an explicit default constructor? It seems that it
: >would disable variables without initializers and members without
: >mention in constructor initializer list. I can't find anything
: >that egcs disallows.
:
: However it allows explicit creation of a temporary that can be bound to
: a reference. Hm... I wonder if that might be useful.
I assume you meant const reference. s/wonder/would be amazed/ :)
Since I can't seem to get a compiler to agree with my understanding,
how about some answers to the following?
struct S { explicit S (); }; // This could be the result of
// explicit S (int = 0);
struct D1 : S { }; // invalid
struct D2 : S { D2 () { } }; // invalid
struct D3 : S { D3 () : S() { } }; // valid
struct A1 { S s; A1 () { } }; // invalid
struct A2 { S s; A2 () : s() { } }; // valid
S s1; // invalid
S s2(); // function declaration
S s3(S()); // function declaration
S s4((S())); // valid or function declaration ???
S s5((0, S())); // valid
S s6 = S(); // valid
S const& rs = S(); // valid
Anything I missed that it disallows?
John
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Valentin Bonnard <Bonnard.V@wanadoo.fr>
Date: 1999/07/28 Raw View
> However there is a point that I think needs addressing and that is what
> happens if the programmer qualifies the copy ctor as explicit?
It doesn't make any sens to do so. I think it has no effect.
--
Valentin Bonnard
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/07/28 Raw View
In article <379E459F.763F@wanadoo.fr>, Valentin Bonnard
<Bonnard.V@wanadoo.fr> writes
>It doesn't make any sens to do so. I think it has no effect.
It prevents pass/return by value while allowing explicit creation of
copies. Somewhat similar to a private copy ctor with a static method to
allow cloning.
Francis Glassborow Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Darin Adler" <darin@bentspoon.com>
Date: 1999/07/28 Raw View
> Since I can't seem to get a compiler to agree with my understanding,
> how about some answers to the following?
>
> struct S { explicit S (); }; // This could be the result of
> // explicit S (int = 0);
As far as I can tell, it doesn't matter if the default constructor is an
explicit constructor. It seems that explicit only affects cases where
there's a type conversion involved.
So in your example, the use of the explicit specifier has no effect.
-- Darin
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: 1999/07/29 Raw View
On 28 Jul 1999 19:02:42 GMT, "Darin Adler" <darin@bentspoon.com> wrote:
:
: > Since I can't seem to get a compiler to agree with my understanding,
: > how about some answers to the following?
: >
: > struct S { explicit S (); }; // This could be the result of
: > // explicit S (int = 0);
:
: As far as I can tell, it doesn't matter if the default constructor is an
: explicit constructor. It seems that explicit only affects cases where
: there's a type conversion involved.
If we make that implicit type conversion, it makes sense. A default
constructor is a conversion from nothing, I guess. However, the
compiler would never implicitely make that conversion.
: So in your example, the use of the explicit specifier has no effect.
Yes. The language must allow it for the case where the default ctor
is a normal conversion ctor with a default parameter.
John
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: 1999/07/29 Raw View
On 28 Jul 1999 19:02:41 GMT, Francis Glassborow
<francis@robinton.demon.co.uk> wrote:
:
: In article <379E459F.763F@wanadoo.fr>, Valentin Bonnard
: <Bonnard.V@wanadoo.fr> writes
: >It doesn't make any sens to do so. I think it has no effect.
:
: It prevents pass/return by value while allowing explicit creation of
: copies. Somewhat similar to a private copy ctor with a static method to
: allow cloning.
Valentin's arguement makes sense also. The copy ctor is a conversion
ctor, it performs the identity conversion. However, explicit prevents
implicit conversions and the compiler would never use an implicit
identity conversion. Pass/return by value uses the copy ctor
explicitly. Declarations using = use the copy ctor explicitly. I
might write static_cast<T>(someT) which would use the copy ctor as
a conversion ctor in that explicit cast; so, the copy ctor must be
a conversion ctor.
See also Darin's comments on explicit default ctor.
As usual, my original response to your question about the explicit
copy ctor shows that the obvious may have nothing to do with
the standard.
John
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/07/29 Raw View
In article <7nnf2t$1d4i@enews1.newsguy.com>, Darin Adler
<darin@bentspoon.com> writes
>> Since I can't seem to get a compiler to agree with my understanding,
>> how about some answers to the following?
>>
>> struct S { explicit S (); }; // This could be the result of
>> // explicit S (int = 0);
>
>As far as I can tell, it doesn't matter if the default constructor is an
>explicit constructor. It seems that explicit only affects cases where
>there's a type conversion involved.
>
>So in your example, the use of the explicit specifier has no effect.
True, but explicit was explicitly allowed on any ctor. Now when someone
changes the code with:
S(int =0);
You will get the desired protection.
Francis Glassborow Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: clamage@eng.sun.com (Steve Clamage)
Date: 1999/07/23 Raw View
Gerhard Menzl <gerhard.menzl@sea.ericsson.se> writes:
>The way I understand explicit constructors, the following code should be
>ill-formed:
> struct X
> {
> X () {}
> explicit X (int i) {}
> };
> X f ()
> {
> int i = 42;
> return i;
> }
> int main ()
> {
> X x = f ();
> return 0;
> };
>As far as I can see, the return statement in f() requires an implicit
>conversion from int to X, which is prohibited by the explicit
>constructor.
Yes. The purpose of 'explicit' is to prevent this sort of
implicit conversion.
--
Steve Clamage, stephen.clamage@sun.com
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: 1999/07/23 Raw View
On 23 Jul 99 00:24:56 GMT, clamage@eng.sun.com (Steve Clamage) wrote:
: Gerhard Menzl <gerhard.menzl@sea.ericsson.se> writes:
: > struct X
: > {
: > X () {}
: > explicit X (int i) {}
: > };
:
: > X f ()
: > {
: > int i = 42;
: > return i;
: > }
:
: >As far as I can see, the return statement in f() requires an implicit
: >conversion from int to X, which is prohibited by the explicit
: >constructor.
And, the meaning of life is lost :)
: Yes. The purpose of 'explicit' is to prevent this sort of
: implicit conversion.
I've wondered about this. The result of 'explicit' does prevent this
sort of 'implicit' conversion. It prevents all copy initializations
regardless of how "explicit" the request. I thought that the
purpose was to prevent surprise conversions. This one is hardly a
surprise. I admit that preventing only surprise conversions would
be near impossible to specify. Yep, it's a bug. I guess that I will
need to get used to (static) casting my returns. That may be good.
John
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/07/24 Raw View
In article <37980270.55870003@news.csrlink.net>, John Potter
<jpotter@falcon.lhup.edu> writes
>I've wondered about this. The result of 'explicit' does prevent this
>sort of 'implicit' conversion. It prevents all copy initializations
>regardless of how "explicit" the request. I thought that the
>purpose was to prevent surprise conversions. This one is hardly a
>surprise. I admit that preventing only surprise conversions would
>be near impossible to specify. Yep, it's a bug. I guess that I will
>need to get used to (static) casting my returns. That may be good.
Nonsense, just get used to writing function style initialisations.
Francis Glassborow Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Gerhard Menzl <gerhard.menzl@sea.ericsson.se>
Date: 1999/07/21 Raw View
The way I understand explicit constructors, the following code should be
ill-formed:
struct X
{
X () {}
explicit X (int i) {}
};
X f ()
{
int i = 42;
return i;
}
int main ()
{
X x = f ();
return 0;
};
As far as I can see, the return statement in f() requires an implicit
conversion from int to X, which is prohibited by the explicit
constructor. One of my compilers, however, accepts it. I would like to
confirm this to be a bug before I submit it to the vendor.
Gerhard Menzl
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: sbnaran@localhost.localdomain (Siemel Naran)
Date: 1999/07/22 Raw View
On 21 Jul 99 01:44:00 GMT, Gerhard Menzl <gerhard.menzl@sea.ericsson.se> wrote:
>The way I understand explicit constructors, the following code should be
>ill-formed:
>
> struct X
> {
> X () {}
> explicit X (int i) {}
> };
>
> X f ()
> {
> int i = 42;
> return i;
> }
>
> int main ()
> {
> X x = f ();
>
> return 0;
> };
Indeed, this is ill-formed.
--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Valentin Bonnard <Bonnard.V@wanadoo.fr>
Date: 1999/07/22 Raw View
Gerhard Menzl wrote:
> The way I understand explicit constructors, the following code should be
> ill-formed:
>
> struct X
> {
> X () {}
> explicit X (int i) {}
> };
>
> X f ()
> {
> int i = 42;
> return i;
> }
It is clearly a bug if your compiler accept this code.
--
Valentin Bonnard
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]