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                       ]