 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Paavo Helde Guest
|
Posted: Thu Nov 23, 2006 8:48 am Post subject: Can copy assignment operator be const? |
|
|
The user-defined copy assignment operator can have exactly one
parameter of type X, X&, const X&, volatile X& or const volatile X&.
However, it is not clear if the function itself can be declared const
or not. IOW, given:
struct X {
X& operator=(const X&) const;
};
is the compiler still entitled to generate a default copy assignment
op?
TIA
Paavo
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
James Kanze Guest
|
Posted: Fri Nov 24, 2006 6:59 am Post subject: Re: Can copy assignment operator be const? |
|
|
Paavo Helde wrote:
| Quote: | Cupu wrote:
Well .. umm .. you're returning a reference so that it can work in
multiple assignments (in the same statement), specifically you're
returning a reference to self (this).
So you're modifing the object .. and then returning a reference to
itself ...
I should think that prevents the method of being const ..
OK, I just tried to make the example as short as possible; the actual
signature is
struct X {
const X& operator=(const X&) const;
};
Anyway, I don't believe this change should affect anyhting, the
assignment operator return type is a reference to *this just by a
common habit and not by the standard.
|
In practice, most of my const assignment operators return void.
Const assignment operators appear most often in proxy classes
where chaining doesn't necessarily make sense, and in fact can
lead to some surprises on the part of the user.
--
James Kanze (Gabi Software) email: james.kanze (AT) gmail (DOT) com
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 |
|
 |
James Kanze Guest
|
Posted: Fri Nov 24, 2006 7:01 am Post subject: Re: Can copy assignment operator be const? |
|
|
Mathias Gaunard wrote:
| Quote: | Paavo Helde wrote:
struct X {
X& operator=(const X&) const;
};
is the compiler still entitled to generate a default copy assignment
op?
It's pretty difficult to modify *this if you make *this const...
Unless X has no member or only mutable ones.
|
So who says that the assignment operator has to modify the
object being assigned to. Proxy classes are a pretty standard
technique for certain things, and they usually have const
assignment operators.
--
James Kanze (Gabi Software) email: james.kanze (AT) gmail (DOT) com
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 |
|
 |
Keith H Duggar Guest
|
Posted: Fri Nov 24, 2006 10:00 am Post subject: Re: Can copy assignment operator be const? |
|
|
Paavo Helde wrote:
| Quote: | That's correct! In this case there is only one mutable
member. The class itself is a smartpointer trying to
forward the constness of itself to the pointed object. As
you can assign to a const T*, the const assignment op
seems justified.
|
What exactly do you mean by "forward the constness of itself
to the pointed object."? Since when does the constness of a
pointer impact the constness of the type pointed to?
T const *
T * const
T const * const
Are significantly different concepts in C++. Are you trying
to create new pointer semantics? If so, why and to what end?
Keith
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Jiang Guest
|
Posted: Sat Nov 25, 2006 4:24 am Post subject: Re: Can copy assignment operator be const? |
|
|
James Kanze wrote:
| Quote: | Mathias Gaunard wrote:
Paavo Helde wrote:
|
[snip]
| Quote: |
So who says that the assignment operator has to modify the
object being assigned to. Proxy classes are a pretty standard
technique for certain things, and they usually have const
assignment operators.
|
Sorry for my ignorance, but would you please explain
a little bit more about the benefit of using const copy
assignment operators in Proxy classes?
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Paavo Helde Guest
|
Posted: Sat Nov 25, 2006 8:33 am Post subject: Re: Can copy assignment operator be const? |
|
|
Keith H Duggar wrote:
| Quote: | Paavo Helde wrote:
That's correct! In this case there is only one mutable
member. The class itself is a smartpointer trying to
forward the constness of itself to the pointed object. As
you can assign to a const T*, the const assignment op
seems justified.
What exactly do you mean by "forward the constness of itself
to the pointed object."? Since when does the constness of a
pointer impact the constness of the type pointed to?
T const *
T * const
T const * const
Are significantly different concepts in C++. Are you trying
to create new pointer semantics? If so, why and to what end?
|
In retrospect, we could have followed the STL iterator design and
define two separate classes, e.g. Ptr and Const_Ptr. However, the
current design has spread over large codebase by now and I would not
want to change this, unless somebody convinces me that I'm doing
something illegal.
In essence, the top-level const of the smartpointer is recycled to
indicate the constness of the pointed object. After all, the top-level
const is not very much used for value types like pointers (there was a
recent thread about this as well; I think the consensus was that one
has to keep the functions short enough anyway so there is not much need
to use top-level const for local data and function arguments). In order
to bypass language constness checks on top-level const, assignment ops
have to be declared const. So the smartpointer we have something like
the following:
class Base; // class hierarchy of dynamically created objects.
struct PVoid {
PVoid(): p_(0) {}
PVoid(const Base* p);
PVoid(const PVoid& b);
~PVoid();
const PVoid& operator=(const Base* p) const;
const PVoid& operator=(const PVoid& b) const;
const Base* operator->() const { return p_; }
Base* operator->() { return p_; }
const Base& operator*() const { return *p_;}
Base& operator*() { return *p_;}
private:
mutable Base* p_;
};
In the end, I have something like following (simplified, in real code
only derived classes are used both for pointers and entity objects).
PVoid a = new Base();
a->f(); // calls non-const f
const PVoid b;
b = a; // would not work without const assignment.
b->f(); // calls const f
This corresponds to:
Base* a = new Base();
a->f(); // calls non-const f
const Base* b;
b = a;
a->f(); // calls const f
So I prefer to think that the smartpointer class is designed this way
in order to keep semantics *unchanged* for this similar syntax. Yes I
know this is not really the case ;-)
Regards
Paavo
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Ulrich Eckhardt Guest
|
Posted: Sat Nov 25, 2006 8:34 am Post subject: Re: Can copy assignment operator be const? |
|
|
Keith H Duggar wrote:
| Quote: | Paavo Helde wrote:
That's correct! In this case there is only one mutable
member. The class itself is a smartpointer trying to
forward the constness of itself to the pointed object. As
you can assign to a const T*, the const assignment op
seems justified.
What exactly do you mean by "forward the constness of itself
to the pointed object."? Since when does the constness of a
pointer impact the constness of the type pointed to?
|
It doesn't, but there are other examples where constness is propagated in a
similar way, e.g. std::vector.
On the other hand, I don't see that this justifies a const assignment
operator. There might be legitimate reasons for proxy objects though, but
it's hard to tell without seeing the whole design.
| Quote: | T const *
T * const
T const * const
Are significantly different concepts in C++. Are you trying
to create new pointer semantics? If so, why and to what end?
|
I can only guess what is the case, but e.g. the typical disadvantage of the
PIMPL pattern is that the compiler doesn't help enforcing const-correct
code when you implement it with a raw pointer. A slightly smarter pointer
would fix that issue by propagating its own constness to the objects it
points to.
Uli
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Abhishek Padmanabh Guest
|
Posted: Sun Nov 26, 2006 4:34 am Post subject: Re: Can copy assignment operator be const? |
|
|
Paavo Helde wrote:
| Quote: | class Base; // class hierarchy of dynamically created objects.
struct PVoid {
PVoid(): p_(0) {}
PVoid(const Base* p);
PVoid(const PVoid& b);
~PVoid();
const PVoid& operator=(const Base* p) const;
const PVoid& operator=(const PVoid& b) const;
const Base* operator->() const { return p_; }
Base* operator->() { return p_; }
const Base& operator*() const { return *p_;}
Base& operator*() { return *p_;}
private:
mutable Base* p_;
};
In the end, I have something like following (simplified, in real code
only derived classes are used both for pointers and entity objects).
PVoid a = new Base();
a->f(); // calls non-const f
const PVoid b;
b = a; // would not work without const assignment.
b->f(); // calls const f
This corresponds to:
Base* a = new Base();
a->f(); // calls non-const f
const Base* b;
b = a;
a->f(); // calls const f
So I prefer to think that the smartpointer class is designed this way
in order to keep semantics *unchanged* for this similar syntax. Yes I
know this is not really the case ;-)
|
Sorry, but mutable members should never form part of the observable
state of an object. If the assignment operator is defined const - it
will not and should not work for non-const objects. And if the object
is const and trying to invoke the assignment is trying to change the
observable state. Which can not be very intuitive. Also, if one wants
to disable the copy assignment then they always have the option of
putting the declaration in the private/protected section.
So, I think what you are trying to achieve is flawed in its
implementation. To propagate const-ness with smart ptrs and objects
pointed to, you may want to consider taking a look at Scott Meyers,
MEC++ Item 28 - Smart pointers (last section - smart pointers and
const). Unless, I mis-understood you. :)
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Gennaro Prota Guest
|
Posted: Mon Nov 27, 2006 10:10 am Post subject: Re: Can copy assignment operator be const? |
|
|
On 26 Nov 2006 13:45:28 -0500, James Kanze wrote:
| Quote: | Jiang wrote:
James Kanze wrote:
Mathias Gaunard wrote:
Paavo Helde wrote:
[snip]
So who says that the assignment operator has to modify the
object being assigned to. Proxy classes are a pretty standard
technique for certain things, and they usually have const
assignment operators.
Sorry for my ignorance, but would you please explain
a little bit more about the benefit of using const copy
assignment operators in Proxy classes?
It's just one common convention. There's no fundamental reason
for it not to be const
|
You are talking about some proxy classes, aren't you? Or do you think
that, for instance, std::bitset<>::reference should have a const copy
assignment operator?
--
Gennaro Prota. For hire.
(to mail me, remove any 'u' from the address)
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
James Kanze Guest
|
Posted: Fri Dec 01, 2006 9:23 am Post subject: Re: Can copy assignment operator be const? |
|
|
Gennaro Prota wrote:
| Quote: | On 28 Nov 2006 10:47:06 -0500, James Kanze wrote:
Gennaro Prota wrote:
FWIW, we were talking about *copy* assignment operators.
I missed that. I thought it was just a question of assignment
operators in general. To tell the truth, I hadn't thought too
much about the question of copy assignment; in at least some
implementations, I don't even support it. (The only operator=
that exists returns void).
Just to be sure we are on the same wavelength: there seems to be no
such a thing as a "const copy assignment operator" (it isn't
considered a copy assignment operator if it is declared const --the
standard seems to say otherwise, but all compilers I tried, including
Comeau, seemed to agree with the above; I think a DR would be in
order, but if you have read Pete Becker's comments in the thread
'Editorial change proposal in 12.8/2', on c.std.c++...).
|
The standard most explicitely says that any user defined
non-template operator= which takes a possibly cv-qualified
version of the class type is a copy assignment operator. Any
compiler which generates a non-const copy assignment operator
when a user-defined const version is there is not conform.
I just tested g++, it gets it right.
As for Pete Becker's comments in c.s.c++, I imagine that what
he's really bored by is people complaining that there defect
report isn't getting priority attention. He (and the other
committee members) are under a lot of pressure right now, and I
can understand their getting irritated by being nagged at for
not picking up some of the less important points as promptly as
the person raising them might like. Being a committee member is
a thankless task; if you contribute seriously, as Pete does,
it's a lot of work, and no matter what you do, some people will
consider it wrong.
| Quote: | I added a bit to the confusion, when asking about bitset<>::reference,
because I forgot a couple of quotation marks: I just meant to ask if
you felt a compelling reason for having a const operator=(const
reference &).
|
As I said, nothing compelling. Except that the default is to
make any function const if one can, and that it is, in some
circles, a recognized hallmark of a proxy, and so helps some in
the documentation.
| Quote: | Thinking about it, however, I don't think it makes a difference.
(And the compiler generated version doesn't work, so my
BitVectorAccessProxy has an error.)
Do you have a const one in your BitVectorAccessProxy?
Actually, I just let the compiler do its thing. Which is wrong,
see below:
I'd imagine you have only mutable data members in it, then (or
that you store a pointer to the corresponding bit-vector,
which makes bit-references not stable under a standard library
swap of their bit-vectors).
On thinking about it: the whole idea behind using a proxy is
that it is in some way transparent. The user never declares
instances of a proxy (although we can't prevent it);
In the case of static/dynamic bitsets access control can help. In my
implementation, for instance, the only non-copy constructor of the
proxy class is private (dynamic_bitset is a friend).
|
That's often what I do, at least today. In the case of my
BitVectorAccessProxy, however, there are technical reasons why
this isn't possible. (I think---I'd have to look at it again.)
| Quote: | the real
reason one might want to support it is for expressions of the
sort:
a[ i ] = b[ j ] = newValue ;
Now, this would work perfectly if there was NO copy assignment
operator, but we can't achieve that; there will always be one.
You mean it would work perfectly relying on the proxy implicit
conversion and a non-copy assignment from value_type?
|
Well, if there were NO copy assignment operator, that's what
would happen. The only assignment operator available would be
the one taking a bool, and since there is an implicit conversion
available...
| Quote: | Yes. But, as you
say,
a[ i ] = b[ j ]
will always lead to consider (and eventually generate) the copy
assignment operator.
|
More correctly (although it really doesn't make any difference),
there is no such thing as a class type in which no copy
assignment operator is declared. The declaration is generated
as soon as the class definition is seen. That operator takes
part in overload resolution, and of course, would be chosen
here.
In my original expression, of course, it would suffice if the
operator=( bool ) returned a bool, rather than a reference to
the proxy.
| Quote: | For this expression to work, it's semantics should be:
Container::AsgnProxy const&
Container::AsgnProxy operator=(
Container::AsgnProxy const& other ) const
{
return ::operator=(
static_cast< Container::value_type> ( other ) ) ;
}
And yes, a const assignment operator works perfectly well here.
I assume you mean "would" work (if there was NO copy assignment).
For the
b[ j ] = newValue ;
part, instead, one usually defines another assignment operator.
|
I'm not sure I'm following you. We're talking about a proxy
here. By definition, it has another assignment operator.
Otherwise, the above would be illegal. The question is how to
make something like:
a[ i ] = b[ j ] = newValue ;
work as expected. Off hand, you either need something like I
just proposed, or the other assignment operator must return
bool.
I'd have to study it. Off hand, it looks like it should work.
Given the name, and it's presumed relationship to std::bitset,
I'd say that it should probably do whatever bitset does.
| Quote: | That is, do you feel that operator=( bool ) should be const?
|
Considered in isolation, I'd probably make it const, because
that corresponds to the conventions in vigor where I work.
Considered as a potential part of the standard, related to
std::bitset, I'd follow the conventions in std::bitset, where it
isn't const.
Note, however, that there is no real reason for it not to be
const. Declare the function const, and all desired uses still
work.
| Quote: | Note that
the bitset/dynamic_bitset case is a bit peculiar (hence my question; I
even supposed that you could restrict the term "proxy" to exclude such
pseudo-reference beasts --I had a look at Design Patterns and I'm not
sure whether "bit references" as we are discussing them here are
proxies in any of the GoF meanings), in that you cannot store a
pointer to the container (because you want a standard library swap on
the containers not to invalidate any proxy object --IOWs the proxies,
like real references, have to refer to the same bits, even if those
bits have changed container).
|
I'm not sure. Typically, as I said, you don't ever declare
variables of a proxy type.
I think if you really want to support STL, and have reference
act as if it were a real reference in some way, you'd have to
also define a "pointer" type, overload &, etc. In practice, no
matter what you do, sooner or later, you're going to run into
problemes. In the end, proxies are just that, proxies. They
act as the real thing in certain, well defined cases, and the
rest, you just don't support. In practice, almost all, if not
all, of the uses of swap on standard containers are to achieve
move semantics---it's an optimization for copy constructing,
then destructing. And you don't allow iterators to float around
when you do it, because they wouldn't be valid if you did the
actual copy construction/destruction. Intuitively, an iterator
points into a container, and having it miraculously change the
container it points into is a sure recepe for unreadable code.
--
James Kanze (Gabi Software) email: james.kanze (AT) gmail (DOT) com
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 |
|
 |
Gennaro Prota Guest
|
Posted: Sat Dec 02, 2006 1:52 am Post subject: Re: Can copy assignment operator be const? |
|
|
On 30 Nov 2006 22:23:42 -0500, James Kanze wrote:
| Quote: | Gennaro Prota wrote:
On 28 Nov 2006 10:47:06 -0500, James Kanze wrote:
Gennaro Prota wrote:
FWIW, we were talking about *copy* assignment operators.
I missed that. I thought it was just a question of assignment
operators in general. To tell the truth, I hadn't thought too
much about the question of copy assignment; in at least some
implementations, I don't even support it. (The only operator=
that exists returns void).
Just to be sure we are on the same wavelength: there seems to be no
such a thing as a "const copy assignment operator" [...] --the
standard seems to say otherwise, but all compilers I tried, including
Comeau, seemed to agree with the above; I think a DR would be in
order, but if you have read Pete Becker's comments in the thread
'Editorial change proposal in 12.8/2', on c.std.c++...).
[...]
Any compiler which generates a non-const copy assignment operator
when a user-defined const version is there is not conform.
|
That's how I read 12.8 (actually that's how I read 12.8/10, on the
grounds that "if" stands, as usually happens in the standard, for "if
and only if")
| Quote: | I just tested g++, it gets it right.
|
Instead I tried the following with Comeau online:
struct X
{
const int x;
X() (0) {}
const X& operator=( const X & ) const { return *this; }
};
int main()
{
X x;
/*const*/ X x2; // add the const to compile successfully
x2 = x;
}
and the error message was
"ComeauTest.c", line 1: error: implicitly generated
assignment operator cannot copy:
const member "X: "
struct X
^
detected during implicit generation of
"X &X::operator=(const X &)" at line 12
| Quote: | As for Pete Becker's comments in c.s.c++, I imagine that what
he's really bored by is people complaining that there defect
report isn't getting priority attention.
|
Too bad that this isn't the right place for discussing such behaviors.
| Quote: | [...] I just meant to ask if
you felt a compelling reason for having a const operator=(const
reference &).
As I said, nothing compelling. Except that the default is to
make any function const if one can,
|
That's what I usually do as well. For the two assignment operators in
dynamic_bitset<>::reference (and other member functions, now that I
think about it) it really didn't occur to me. My bad :-)
| Quote: | and that it is, in some
circles, a recognized hallmark of a proxy, and so helps some in
the documentation.
Thinking about it, however, I don't think it makes a difference.
(And the compiler generated version doesn't work, so my
BitVectorAccessProxy has an error.)
Do you have a const one in your BitVectorAccessProxy?
Actually, I just let the compiler do its thing. Which is wrong,
see below:
I'd imagine you have only mutable data members in it, then (or
that you store a pointer to the corresponding bit-vector,
which makes bit-references not stable under a standard library
swap of their bit-vectors).
On thinking about it: the whole idea behind using a proxy is
that it is in some way transparent. The user never declares
instances of a proxy (although we can't prevent it);
In the case of static/dynamic bitsets access control can help. In my
implementation, for instance, the only non-copy constructor of the
proxy class is private (dynamic_bitset is a friend).
That's often what I do, at least today. In the case of my
BitVectorAccessProxy, however, there are technical reasons why
this isn't possible. (I think---I'd have to look at it again.)
the real
reason one might want to support it is for expressions of the
sort:
a[ i ] = b[ j ] = newValue ;
Now, this would work perfectly if there was NO copy assignment
operator, but we can't achieve that; there will always be one.
You mean it would work perfectly relying on the proxy implicit
conversion and a non-copy assignment from value_type?
Well, if there were NO copy assignment operator, that's what
would happen. The only assignment operator available would be
the one taking a bool, and since there is an implicit conversion
available...
Yes. But, as you
say,
a[ i ] = b[ j ]
will always lead to consider (and eventually generate) the copy
assignment operator.
More correctly (although it really doesn't make any difference),
there is no such thing as a class type in which no copy
assignment operator is declared. The declaration is generated
as soon as the class definition is seen. That operator takes
part in overload resolution, and of course, would be chosen
here.
In my original expression, of course, it would suffice if the
operator=( bool ) returned a bool, rather than a reference to
the proxy.
For this expression to work, it's semantics should be:
Container::AsgnProxy const&
Container::AsgnProxy operator=(
Container::AsgnProxy const& other ) const
{
return ::operator=(
static_cast< Container::value_type> ( other ) ) ;
}
And yes, a const assignment operator works perfectly well here.
I assume you mean "would" work (if there was NO copy assignment).
For the
b[ j ] = newValue ;
part, instead, one usually defines another assignment operator.
I'm not sure I'm following you.
|
You are following I just stated the obvious.
| Quote: | We're talking about a proxy
here. By definition, it has another assignment operator.
Otherwise, the above would be illegal. The question is how to
make something like:
a[ i ] = b[ j ] = newValue ;
work as expected. Off hand, you either need something like I
just proposed, or the other assignment operator must return
bool.
My
question is: would you consider my implementation of
dynamic_bitset::reference defective in this regard?
http://preview.tinyurl.com/uew6m
I'd have to study it. Off hand, it looks like it should work.
|
Well, it works But my question was more on the style side: "how
would you consider the lack of const?". I'm happy to hear that you
don't consider adding it compelling, though if I had thought of it I'd
have used it.
| Quote: | Given the name, and it's presumed relationship to std::bitset,
I'd say that it should probably do whatever bitset does.
That is, do you feel that operator=( bool ) should be const?
Considered in isolation, I'd probably make it const, because
that corresponds to the conventions in vigor where I work.
Considered as a potential part of the standard, related to
std::bitset, I'd follow the conventions in std::bitset, where it
isn't const.
Note, however, that there is no real reason for it not to be
const. Declare the function const, and all desired uses still
work.
|
Propagating the const qualification on a bunch of other functions (and
on at least a return type), yes The idea to return a bool from
bool operator=(bool x) const { do_assign(x); return x; }
is particularly nice.
| Quote: |
Note that
the bitset/dynamic_bitset case is a bit peculiar (hence my question; I
even supposed that you could restrict the term "proxy" to exclude such
pseudo-reference beasts --I had a look at Design Patterns and I'm not
sure whether "bit references" as we are discussing them here are
proxies in any of the GoF meanings), in that you cannot store a
pointer to the container (because you want a standard library swap on
the containers not to invalidate any proxy object --IOWs the proxies,
like real references, have to refer to the same bits, even if those
bits have changed container).
I'm not sure. Typically, as I said, you don't ever declare
variables of a proxy type.
I think if you really want to support STL, and have reference
act as if it were a real reference in some way, you'd have to
also define a "pointer" type, overload &, etc.
|
One idea I wanted to experiment with was to have address-of return an
iterator when applied to a reference. So far I haven't had time (and
spurs) for that, though.
| Quote: | [hard-to-disagree-with comments snipped ]
|
--
Gennaro Prota. C++ developer. For hire.
(to mail me, remove any 'u' from the address)
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
James Kanze Guest
|
Posted: Sat Dec 02, 2006 10:10 am Post subject: Re: Can copy assignment operator be const? |
|
|
Gennaro Prota wrote:
| Quote: | On 30 Nov 2006 22:23:42 -0500, James Kanze wrote:
Gennaro Prota wrote:
On 28 Nov 2006 10:47:06 -0500, James Kanze wrote:
Gennaro Prota wrote:
FWIW, we were talking about *copy* assignment operators.
I missed that. I thought it was just a question of assignment
operators in general. To tell the truth, I hadn't thought too
much about the question of copy assignment; in at least some
implementations, I don't even support it. (The only operator=
that exists returns void).
Just to be sure we are on the same wavelength: there seems to be no
such a thing as a "const copy assignment operator" [...] --the
standard seems to say otherwise, but all compilers I tried, including
Comeau, seemed to agree with the above; I think a DR would be in
order, but if you have read Pete Becker's comments in the thread
'Editorial change proposal in 12.8/2', on c.std.c++...).
[...]
Any compiler which generates a non-const copy assignment operator
when a user-defined const version is there is not conform.
That's how I read 12.8 (actually that's how I read 12.8/10, on the
grounds that "if" stands, as usually happens in the standard, for "if
and only if")
I just tested g++, it gets it right.
Instead I tried the following with Comeau online:
struct X
{
const int x;
X() (0) {}
const X& operator=( const X & ) const { return *this; }
};
int main()
{
X x;
/*const*/ X x2; // add the const to compile successfully
x2 = x;
}
and the error message was
"ComeauTest.c", line 1: error: implicitly generated
assignment operator cannot copy:
const member "X: "
struct X
^
detected during implicit generation of
"X &X::operator=(const X &)" at line 12
|
Looks like a bug. My test was a bit different; my class was
empty, but I instrumented a const copy constructor, and it was
called; the compiler didn't generate a non-const one to replace
it.
| Quote: | As for Pete Becker's comments in c.s.c++, I imagine that what
he's really bored by is people complaining that there defect
report isn't getting priority attention.
Too bad that this isn't the right place for discussing such behaviors.
|
There's nothing to discuss. Pete's contributing a lot to the
standardization effort. Volentarily. If you want to ensure
that your points receive the attention you want them to receive,
there's only one way: participate yourself. I'm sure that every
member of the committee appreciates a polite indication
concerning how and where the standard could be improved. I'm
just as sure that none of them appreciate someone jumping on
their back because their suggestion wasn't treated with as much
importance as they wanted. There are a lot of issues competing
for attention, and if you find that some aren't getting enough
attention, you're welcome to lend a hand.
[...]
| Quote: | My
question is: would you consider my implementation of
dynamic_bitset::reference defective in this regard?
http://preview.tinyurl.com/uew6m
I'd have to study it. Off hand, it looks like it should work.
Well, it works
|
That's a broad statement. Define "works". Can I write
something like:
sometype* p = &a[i] ;
?
| Quote: | But my question was more on the style side: "how would you
consider the lack of const?". I'm happy to hear that you don't
consider adding it compelling, though if I had thought of it
I'd have used it.
|
Off hand, and without having seen a full description of the
class, I got the impression that it was designed to be the
dynamic equivalent of std::bitset. If so, it should do what
std::bitset does, unless there is an imperative reason to do
otherwise.
| Quote: | Given the name, and it's presumed relationship to std::bitset,
I'd say that it should probably do whatever bitset does.
That is, do you feel that operator=( bool ) should be const?
Considered in isolation, I'd probably make it const, because
that corresponds to the conventions in vigor where I work.
Considered as a potential part of the standard, related to
std::bitset, I'd follow the conventions in std::bitset, where it
isn't const.
Note, however, that there is no real reason for it not to be
const. Declare the function const, and all desired uses still
work.
Propagating the const qualification on a bunch of other functions (and
on at least a return type), yes The idea to return a bool from
bool operator=(bool x) const { do_assign(x); return x; }
is particularly nice.
|
Maybe. Is it intended that users declare things like
dynamic_bitset::reference? Do you want to support something
like:
dynamic_bitset::reference
someFunction()
{
// ...
return a[ i ] = someValue ;
}
(I could do this with a vector<int> and vector<int>::reference,
for example.)
Until you define exactly what you want to support, and what not,
it's impossible to say what is a good idea, and what isn't. My
proxies don't support this, and it doesn't bother my in the
style of coding I use. But other people have different styles;
there is a reason why = on the built in types results in an
lvalue, for example, even if my code never uses this fact.
--
James Kanze (Gabi Software) email: james.kanze (AT) gmail (DOT) com
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 |
|
 |
Gennaro Prota Guest
|
Posted: Sun Dec 03, 2006 3:57 am Post subject: Re: Can copy assignment operator be const? |
|
|
On 2 Dec 2006 03:08:03 -0500, James Kanze wrote:
| Quote: | [...]
My question is: would you consider my implementation of
dynamic_bitset::reference defective in this regard?
http://preview.tinyurl.com/uew6m
I'd have to study it. Off hand, it looks like it should work.
Well, it works :-)
That's a broad statement. Define "works".
|
Define "should work" :-P
| Quote: | Can I write something like:
sometype* p = &a[i] ;
?
|
class reference {
...
void operator&(); // left undefined
...
};
| Quote: | [...]
The idea to return a bool from
bool operator=(bool x) const { do_assign(x); return x; }
is particularly nice.
Maybe. Is it intended that users declare things like
dynamic_bitset::reference? Do you want to support something
like:
dynamic_bitset::reference
someFunction()
{
// ...
return a[ i ] = someValue ;
}
(I could do this with a vector<int> and vector<int>::reference,
for example.)
|
You seem to be jumping the gun. I didn't say I'm going to use it, just
that the idea is nice. It isn't universally appliable. In my case I
have to return a (const) refererence &; it was my intent to support
the above (with "typename" and a couple of angle brackets), and it
worked last time I touched the code, but I don't think the issue has
received much scrutiny.
--
Gennaro Prota. C++ developer. For hire.
(to mail me, remove any 'u' from the address)
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Gennaro Prota Guest
|
Posted: Sun Dec 03, 2006 5:22 pm Post subject: Re: Can copy assignment operator be const? |
|
|
On 2 Dec 2006 16:57:39 -0500, Gennaro Prota wrote:
| Quote: | it was my intent to support
the above (with "typename" and a couple of angle brackets)
|
Correcting myself: "...the above (with a couple of angle
brackets)...". I think I should sleep a little more :-/
--
Gennaro Prota. C++ developer. For hire.
(to mail me, remove any 'u' from the address)
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Gennaro Prota Guest
|
Posted: Tue Dec 12, 2006 7:48 am Post subject: Re: Can copy assignment operator be const? |
|
|
On 23 Nov 2006 13:17:02 -0500, Paavo Helde wrote:
| Quote: | OK, I just tried to make the example as short as possible; the actual
signature is
struct X {
const X& operator=(const X&) const;
};
Anyway, I don't believe this change should affect anyhting, the
assignment operator return type is a reference to *this just by a
common habit and not by the standard.
I think I agree with Ahti Legonkov in another post that the compiler is
not allowed to generate its own assignment op.
|
One of the committee members kindly indicated me this core issue
<http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#574>
The comments, there, go in the direction of allowing the generation
but very likely the issue hasn't been throughly discussed yet; the
situation you outline above has been pointed out so I believe there's
a concrete chance for a U-turn.
--
Gennaro Prota. C++ developer. For hire.
(to mail me, remove any 'u' from the address)
--
[ 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
|
|