Topic: Copying objects with mutable non-static data members
Author: Wolfgang.Roehrl@de.gi-de.com
Date: Mon, 20 Dec 2004 22:35:03 CST Raw View
Do you agree that the following code is legal C++?
struct PTR
{
PTR ();
PTR (PTR&);
PTR& operator= (PTR&);
private:
PTR (const PTR&);
PTR& operator= (const PTR&);
void* ptr;
};
struct XYZ
{
XYZ (PTR& p) : ptr(p) {}
mutable PTR ptr;
};
XYZ f1 ();
XYZ f2 (void) { return f1(); }
void f3 (XYZ& dst, const XYZ& src) { dst = src; }
Both the Comeau online compiler and gcc 3.3 reject the code because they
fail
to synthesize the copy constructor respectively the copy assignment
operator
for struct XYZ. (For a more detailed discussion with the GNU compiler
writers
see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18975.)
I think that the code above is legal for the following reasons:
- The compiler-synthetized copy constructor should be _declared_ as
"XYZ::XYZ (const XYZ&);" since PTR has a (private) copy constructor whose
first parameter is "const PTR&". (Cf. 12.8/5; it doesn't matter if the
copy
constructor is accessible.)
- The compiler-synthetized copy assignment operator should be _declared_ as
"XYZ& XYZ::operator= (const XYZ&);" since PTR has a (private) copy
assignment
operator whose first parameter is "const PTR&". (Cf. 12.8/10; it doesn't
matter if the copy assignment operator is accessible.)
- If the compiler-synthetized copy constructor is _defined_ it should use
the
copy constructor of PTR (cf. 12.8/8). Since the member ptr of XYZ is
_mutable_
the (public) copy constructor PTR::PTR (PTR&) should be called after
overload
resolution: "PTR::PTR (PTR&)" is a better match than "PTR::PTR (const
PTR&)".
- The same reasoning holds if the compiler-synthetized copy assignment
operator is _defined_.
Wolfgang
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: invalid@bigfoot.com (Bob Hairgrove)
Date: Tue, 21 Dec 2004 17:57:21 GMT Raw View
On Mon, 20 Dec 2004 22:35:03 CST, Wolfgang.Roehrl@de.gi-de.com wrote:
[snip]
>- The compiler-synthetized copy assignment operator should be _declared_ as
> "XYZ& XYZ::operator= (const XYZ&);" since PTR has a (private) copy
> assignment operator whose first parameter is "const PTR&".
> (Cf. 12.8/10; it doesn't matter if the copy assignment operator is accessible.)
See 12.8.12: it DOES matter that the assignment operator for PTR
taking PTR const & is inaccessible.
--
Bob Hairgrove
NoSpamPlease@Home.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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: invalid@bigfoot.com (Bob Hairgrove)
Date: Wed, 22 Dec 2004 02:30:12 GMT Raw View
On Mon, 20 Dec 2004 22:35:03 CST, Wolfgang.Roehrl@de.gi-de.com wrote:
>struct PTR
>{
> PTR ();
> PTR (PTR&);
> PTR& operator= (PTR&);
>
>private:
> PTR (const PTR&);
> PTR& operator= (const PTR&);
>
> void* ptr;
>};
>
>
>struct XYZ
>{
> XYZ (PTR& p) : ptr(p) {}
>
> mutable PTR ptr;
>};
>
>
>XYZ f1 ();
>
>
>XYZ f2 (void) { return f1(); }
>void f3 (XYZ& dst, const XYZ& src) { dst = src; }
I think there are actually two issues here:
(1) PTR::op= taking non-const PTR& hides the other version;
(2) if the PTR::op= taking non-const PTR& is removed and XYZ made a
friend of PTR, it compiles.
Since PTR is mutable, there probably isn't a need for the first
PTR::op= anyway (taking non-const PTR& as argument).
--
Bob Hairgrove
NoSpamPlease@Home.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://www.jamesd.demon.co.uk/csc/faq.html ]