 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Alf P. Steinbach Guest
|
Posted: Sat May 20, 2006 9:21 pm Post subject: Can 'operator T const& () const' do any harm? |
|
|
I gather that with C++0x we'll be able to write
class T { public: T(){} private: T( T const& ); };
void foo( T const& ) {}
int main() { foo( T() ); }
Currently this code is rejected by Visual C++ 7.1 (with option /Za),
Comeau Online version 4.3.3, and g++ 3.4.4.
However, this code:
class NoCopy
{
public: NoCopy() {}
private: NoCopy( NoCopy const& ); NoCopy& operator=( NoCopy const& );
};
class T: public NoCopy {};
void foo( T const& ) {}
int main() { foo( T() ); }
is accepted by two of the three compilers mentioned above; only g++
produces a compilation error (emits a diagnostic, barfs, whatever).
To make the code compile also with g++ one possibility is to do
class T: public NoCopy
{
public: operator T const& () const { return *this; }
};
This is IMO bad from a design point of view, because it relies on
convention (having this repeated in every class).
But can it do harm, e.g. unintentionally allow something Bad, or
disallow something Good?
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Bronek Kozicki Guest
|
Posted: Tue May 23, 2006 11:21 am Post subject: Re: Can 'operator T const& () const' do any harm? |
|
|
Alf P. Steinbach wrote:
| Quote: | However, this code:
class NoCopy
{
public: NoCopy() {}
private: NoCopy( NoCopy const& ); NoCopy& operator=( NoCopy const& );
};
class T: public NoCopy {};
void foo( T const& ) {}
int main() { foo( T() ); }
is accepted by two of the three compilers mentioned above; only g++
produces a compilation error (emits a diagnostic, barfs, whatever).
|
interesting issue. The code above is IMVHO valid, but it exploits loophole in
the standard. This loophole is entirely removed (and replaced with wide open
door) by resolution of CWG issue 391
| Quote: | To make the code compile also with g++ one possibility is to do
class T: public NoCopy
{
public: operator T const& () const { return *this; }
};
This is IMO bad from a design point of view, because it relies on
convention (having this repeated in every class).
But can it do harm, e.g. unintentionally allow something Bad, or
disallow something Good?
|
it will allow implicit conversion of your rvalues to lvalues (which IMHO is
bad) and make use of rvalue-references problematic once you port the code to
C++0x compliant compiler
B.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Thomas Mang Guest
|
Posted: Tue May 23, 2006 2:21 pm Post subject: Re: Can 'operator T const& () const' do any harm? |
|
|
"Alf P. Steinbach" <alfps (AT) start (DOT) no> schrieb im Newsbeitrag
news:4d66h4F190i9lU1 (AT) individual (DOT) net...
| Quote: | I gather that with C++0x we'll be able to write
class T { public: T(){} private: T( T const& ); };
void foo( T const& ) {}
int main() { foo( T() ); }
Currently this code is rejected by Visual C++ 7.1 (with option /Za),
Comeau Online version 4.3.3, and g++ 3.4.4.
However, this code:
class NoCopy
{
public: NoCopy() {}
private: NoCopy( NoCopy const& ); NoCopy& operator=( NoCopy
const& );
};
class T: public NoCopy {};
void foo( T const& ) {}
int main() { foo( T() ); }
is accepted by two of the three compilers mentioned above; only g++
produces a compilation error (emits a diagnostic, barfs, whatever).
|
Which makes me believe the minority is correct.
The T bound to the reference is an r-value. According to 8.5.3, second
bullet, the copy constructor for T nees to be available, even if the
r-value
is directly bound to the reference.
IOW, if that's correct, forget your conversion opertor, but rewrite the
expression calling foo instead.
Thomas
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Bronek Kozicki Guest
|
Posted: Wed May 24, 2006 4:21 pm Post subject: Re: Can 'operator T const& () const' do any harm? |
|
|
Thomas Mang wrote:
| Quote: | Which makes me believe the minority is correct.
The T bound to the reference is an r-value. According to 8.5.3, second
bullet, the copy constructor for T nees to be available, even if the
|
copy constructor implicitly declared by language in class T (derived from
NoCopy) is accessible, even though one could think that it is not. The
mechanism that makes type T non-copyable is not declaration, but definition of
such implicit copy constructor (which renders program ill-formed if copy
constructor of subobject is non-accessible - for details see clause 12.8/7 ) .
Clause 8.5.3/5 is rather inaccurate because it does not use word "accessible"
but "callable" instead, but given the context I believe that it refers to
declaration, not definition of the copy constructor. This is the "loophole" I
referred to in my previous message. Anyway, now that the "offending" part of
8.5.3 is about to be removed, we just need to wait for compiler implementors
to catch up. Hopefully before 2009 ...
B.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Thu May 25, 2006 2:21 pm Post subject: Re: Can 'operator T const& () const' do any harm? |
|
|
Thomas Mang wrote:
| Quote: | "Alf P. Steinbach" <alfps (AT) start (DOT) no> schrieb im Newsbeitrag
news:4d66h4F190i9lU1 (AT) individual (DOT) net...
I gather that with C++0x we'll be able to write
class T { public: T(){} private: T( T const& ); };
void foo( T const& ) {}
int main() { foo( T() ); }
Currently this code is rejected by Visual C++ 7.1 (with
option /Za), Comeau Online version 4.3.3, and g++ 3.4.4.
However, this code:
class NoCopy
{
public: NoCopy() {}
private: NoCopy( NoCopy const& ); NoCopy& operator=( NoCopy
const& );
};
class T: public NoCopy {};
void foo( T const& ) {}
int main() { foo( T() ); }
is accepted by two of the three compilers mentioned above;
only g++ produces a compilation error (emits a diagnostic,
barfs, whatever).
Which makes me believe the minority is correct. The T bound to
the reference is an r-value. According to 8.5.3, second
bullet, the copy constructor for T nees to be available, even
if the r-value is directly bound to the reference.
|
It's a little bit more subtle than that. In class T, above,
there is an implicitly declared publically accessible copy
constructor, see §12.8/4. You have to go down to §12.8/7 to see
that 1) if the implicitly declared constructor is implicitly
defined, it is an error. And the normative text isn't really
that clear that the constructor will be implicitly defined in
this case -- all we have is a non-normative note saying that if
the constructor will be implicitly defined even if it is elided,
and a reference to 12.2, where it says clearly that the case in
question is assimilated to eliding the constructor. So while it
is clear that the intent is for this to be illegal, I don't
think it is 100% clear from just the normative text.
| Quote: | IOW, if that's correct, forget your conversion opertor, but
rewrite the expression calling foo instead.
|
The code with the conversion operator is correct. I wouldn't do
it, because I'd be afraid of it making other calls ambiguous,
but the example he posted is guaranteed to work according to the
standard.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|