Topic: semantics of == and copying


Author: jth02@arcor.de (Jens Theisen)
Date: Mon, 11 Sep 2006 02:13:57 GMT
Raw View
Hello,

I'm wondering what certain requirements in the standard precisely
mean.

The CopyConstructible (likewise Assignable) requirement says t and
T(t) should be "equivalent". Is it specified anywhere what this
actually means?  Are they not equivalent if, say, foo(t) is different
from foo(T(t)) for some foo? Clearly &t and &T(t) are different.

The EqualityComparable requirement says that == should be an
equivalence relation over its domain. However, I don't see a
requirement for t == T(t). After all, a type does not have to be
copyable in order to be EqualityComparable.

Does the standard say something about the case when both requirements
are met? Is t == T(t) required then?

In particular, in the case of ForwardIterators, it is required that
i == j implies ++i == ++j if both are dereferencable. This strongly
appears to imply the latter, since it would otherwise be a rather
meaningless requirement.

Can anyone point me to the some information about this?

Cheers,

Jens

---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: "Greg Herlihy" <greghe@pacbell.net>
Date: Mon, 11 Sep 2006 09:42:42 CST
Raw View
Jens Theisen wrote:
> Hello,
>
> I'm wondering what certain requirements in the standard precisely
> mean.
>
> The CopyConstructible (likewise Assignable) requirement says t and
> T(t) should be "equivalent". Is it specified anywhere what this
> actually means?  Are they not equivalent if, say, foo(t) is different
> from foo(T(t)) for some foo? Clearly &t and &T(t) are different.

No, the definition of CopyConstructible is not stating that t and T(t)
are generally equivalent. Instead the equivalence applies to this
expression:

     T(t)

So for a CopyConstructible T class,  the "t" in this expression is
equivalent to "T(t)". In other words, replacing one with the other like
so:

     T(T(t))

constructs a T object of the same value as the original.

> The EqualityComparable requirement says that == should be an
> equivalence relation over its domain. However, I don't see a
> requirement for t == T(t). After all, a type does not have to be
> copyable in order to be EqualityComparable.

> Does the standard say something about the case when both requirements
> are met? Is t == T(t) required then?

No, there is no CopyConstructible requirement that the expression t ==
T(t) even has to be defined (often it will not be) - much less that
such a test has to evaluate to true.

> In particular, in the case of ForwardIterators, it is required that
> i == j implies ++i == ++j if both are dereferencable. This strongly
> appears to imply the latter, since it would otherwise be a rather
> meaningless requirement.

I don't see any connection between iterators and the CopyConstructible
requirements. The iterator requirement is simply stating that the items
in a container have a single, fixed order whenever a program iterates
through the container. In other words, no two iterations through the
same container will visit the elements in an order any different than
the other.

Greg

---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: "Chris Jefferson" <4zumanga@gmail.com>
Date: Mon, 11 Sep 2006 09:41:42 CST
Raw View
Jens Theisen wrote:
> Hello,
>
> I'm wondering what certain requirements in the standard precisely
> mean.
>
> The CopyConstructible (likewise Assignable) requirement says t and
> T(t) should be "equivalent". Is it specified anywhere what this
> actually means?  Are they not equivalent if, say, foo(t) is different
> from foo(T(t)) for some foo? Clearly &t and &T(t) are different.
>
> The EqualityComparable requirement says that == should be an
> equivalence relation over its domain. However, I don't see a
> requirement for t == T(t). After all, a type does not have to be
> copyable in order to be EqualityComparable.
>
> Does the standard say something about the case when both requirements
> are met? Is t == T(t) required then?
>
> In particular, in the case of ForwardIterators, it is required that
> i == j implies ++i == ++j if both are dereferencable. This strongly
> appears to imply the latter, since it would otherwise be a rather
> meaningless requirement.
>
> Can anyone point me to the some information about this?
>

Unfortunatly I believve that equivalent in this case is something which
is very hard to exactly define. While there is no good definition about
what it should mean, it is usually fairly obvious what it means in any
context, meaning in general the copy "acts the same as the original".
Like you say, this will not be true if you take it's address, but you
can expect any iterator operations on both copies will produce the same
results.

I believe (someone else may correct me) there have been attempts to
define exactly what equivalent means and there always ends up being a
case where it doesn't act like people would reasonably expect.

Chris

---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: jdennett@acm.org (James Dennett)
Date: Mon, 11 Sep 2006 17:18:11 GMT
Raw View
Greg Herlihy wrote:
> Jens Theisen wrote:
>> Hello,
>>
>> I'm wondering what certain requirements in the standard precisely
>> mean.
>>
>> The CopyConstructible (likewise Assignable) requirement says t and
>> T(t) should be "equivalent". Is it specified anywhere what this
>> actually means?  Are they not equivalent if, say, foo(t) is different
>> from foo(T(t)) for some foo? Clearly &t and &T(t) are different.
>
> No, the definition of CopyConstructible is not stating that t and T(t)
> are generally equivalent.

That's what it's intended to do though; it's saying that
the copy constructor really does make copies.

> Instead the equivalence applies to this
> expression:
>
>      T(t)
>
> So for a CopyConstructible T class,  the "t" in this expression is
> equivalent to "T(t)". In other words, replacing one with the other like
> so:
>
>      T(T(t))
>
> constructs a T object of the same value as the original.

A copy constructor that returned a constant value, ignoring
its argument, would satisfy that condition, as would any
other idempotent operation such as a projection.  That's
not what is wanted.

>> The EqualityComparable requirement says that == should be an
>> equivalence relation over its domain. However, I don't see a
>> requirement for t == T(t). After all, a type does not have to be
>> copyable in order to be EqualityComparable.
>
>> Does the standard say something about the case when both requirements
>> are met? Is t == T(t) required then?
>
> No, there is no CopyConstructible requirement that the expression t ==
> T(t) even has to be defined (often it will not be) - much less that
> such a test has to evaluate to true.

There's a clear implication, however, that if == is defined
with its normal meaning then it should evaluate to true.

-- James

---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: jth02@arcor.de (Jens Theisen)
Date: Mon, 11 Sep 2006 23:40:14 GMT
Raw View
"Chris Jefferson" <4zumanga@gmail.com> writes:

> Unfortunatly I believve that equivalent in this case is something which
> is very hard to exactly define. While there is no good definition about
> what it should mean, it is usually fairly obvious what it means in any
> context, meaning in general the copy "acts the same as the original".
> Like you say, this will not be true if you take it's address, but you
> can expect any iterator operations on both copies will produce the same
> results.

What led me to this question were considerations about forward
iterators, which require s == t -> ++s == ++t. However, if not even t
 == T(t) is required than this other requirement is worth little.

A forward iterator's operator == could be implemented by yielding true
only comparing two past-the-end values. All other comparisons can
evaluate to false without formally braking the requirements.

That's probably not the intention of the standard.

Is this a defect?

Jens

---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: "kanze" <kanze@gabi-soft.fr>
Date: Tue, 12 Sep 2006 12:35:33 CST
Raw View
Jens Theisen wrote:
> "Chris Jefferson" <4zumanga@gmail.com> writes:

> > Unfortunatly I believve that equivalent in this case is
> > something which is very hard to exactly define. While there
> > is no good definition about what it should mean, it is
> > usually fairly obvious what it means in any context, meaning
> > in general the copy "acts the same as the original".  Like
> > you say, this will not be true if you take it's address, but
> > you can expect any iterator operations on both copies will
> > produce the same results.

> What led me to this question were considerations about forward
> iterators, which require s == t -> ++s == ++t. However, if not
> even t == T(t) is required than this other requirement is
> worth little.

> A forward iterator's operator == could be implemented by
> yielding true only comparing two past-the-end values. All
> other comparisons can evaluate to false without formally
> braking the requirements.

> That's probably not the intention of the standard.

> Is this a defect?

Good question.  In practice, I've had no trouble with iterators
which used a.isAtEnd() == b.isAtEnd() as the implementation of
==: two iterators are equal if both are at the end of the
sequence, or neither is.  I don't think that the intent was that
this be guaranteed, but is seems to work in practice (although
it doesn't meet the formal requirements you mention).

I've been unable to find anything more precise either.

--
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


---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: "Greg Herlihy" <greghe@pacbell.net>
Date: Wed, 13 Sep 2006 10:03:41 CST
Raw View
Jens Theisen wrote:
> "Chris Jefferson" <4zumanga@gmail.com> writes:
>
> > Unfortunatly I believve that equivalent in this case is something which
> > is very hard to exactly define. While there is no good definition about
> > what it should mean, it is usually fairly obvious what it means in any
> > context, meaning in general the copy "acts the same as the original".
> > Like you say, this will not be true if you take it's address, but you
> > can expect any iterator operations on both copies will produce the same
> > results.
>
> What led me to this question were considerations about forward
> iterators, which require s == t -> ++s == ++t. However, if not even t
>  == T(t) is required than this other requirement is worth little.

X(a) == a is a necessary precondition for forward iterators (it's
listed third in the table of forward iterator requirements).

Greg

---
[ 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.comeaucomputing.com/csc/faq.html                      ]