Topic: template operator =


Author: Carl Daniel <cpdaniel@pacbell.net>
Date: Sat, 3 Nov 2001 20:13:41 GMT
Raw View
{
mods - this is a re-re-re-post.  The previous copies fell into the ether it
seems - never even got confirmation of them reaching the moderation queue.
appologies for the re-re-post being HTML :)
}

I recently spent an afternoon tracking down a bug which ultimately was
caused by the compiler not using a "template assignment operator" where I
expected.

I'm aware of the rule in the Standard that says that a constructor template
is never a copy constructor, but is there any similar rule for operator=?
So far, I haven't been able to find one.

To wit:

class X
{
   template <class Y>
   X& operator=(const Y& rhs) { return *this; }
};

void foo()
{
   X x;
   X y;
   x = y;    // 1
}

Does the assigment at //1 use the templated assignment operator provided, or
does it use the implicitly generated assignment operator?

-cd

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: dmeyer@dmeyer.net ()
Date: Sun, 4 Nov 2001 13:55:57 GMT
Raw View
According to Carl Daniel  <cpdaniel@pacbell.net>:
> I recently spent an afternoon tracking down a bug which ultimately was
> caused by the compiler not using a "template assignment operator" where I
> expected.
>
> I'm aware of the rule in the Standard that says that a constructor template
> is never a copy constructor, but is there any similar rule for operator=?
> So far, I haven't been able to find one.

The problem in your example is that

    1) X& X::operator=<X>(const X&)
and
    2) X& X::operator=(const X&)

are different things.  If you don't supply #2, the compiler will
generate it.  And once the compiler has generated #2, it's a closer
match than #1 and so will be preferred.

Anyway, that's my take on it.
--
Dave Meyer
dmeyer@dmeyer.net

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: Sun, 4 Nov 2001 17:19:02 GMT
Raw View
Carl Daniel wrote:
>
> {
> mods - this is a re-re-re-post.  The previous copies fell into the ether it
> seems - never even got confirmation of them reaching the moderation queue.
> appologies for the re-re-post being HTML :)
> }
>
> I recently spent an afternoon tracking down a bug which ultimately was
> caused by the compiler not using a "template assignment operator" where I
> expected.
>
> I'm aware of the rule in the Standard that says that a constructor template
> is never a copy constructor, but is there any similar rule for operator=?
> So far, I haven't been able to find one.
>
> To wit:
>
> class X
> {
>    template <class Y>
>    X& operator=(const Y& rhs) { return *this; }
> };
>
> void foo()
> {
>    X x;
>    X y;
>    x = y;    // 1
> }
>
> Does the assigment at //1 use the templated assignment operator provided, or
> does it use the implicitly generated assignment operator?

For an actual copy assignment, the implicitly generated copy assignment
operator is always at least as good a match as any particular template
instantiation. Therefore, the rules of function overloading always favor
it over the template.

In order to use the template, in a context where the implicit function
would also work, you have to create a situation where the implicit
function is a less than perfect match, and the template is a better
match. For instance:

class Y
{
 operator X(){ return X();}
};

void bar()
{
 X x;
 Y y;
 x = y;
}

In this case, without the template the compler would have invoked
x.operator=(y.operator X()). Because the template is present, it will
instead invoke x.operator=<Y>(y). The rule that favors a better
conversion sequence has higher priority than the rule which favors the
non-template function (13.3.3p1).

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: cpdaniel@pacbell.net (Carl Daniel)
Date: Sun, 4 Nov 2001 23:46:14 GMT
Raw View
dmeyer@dmeyer.net () wrote in message news:<9s25h1$9l2$1@jhereg.dmeyer.net>...
> According to Carl Daniel  <cpdaniel@pacbell.net>:
> >
> > I'm aware of the rule in the Standard that says that a constructor template
> > is never a copy constructor, but is there any similar rule for operator=?
> > So far, I haven't been able to find one.
>
> The problem in your example is that
>
>     1) X& X::operator=<X>(const X&)
> and
>     2) X& X::operator=(const X&)
>
> are different things.  If you don't supply #2, the compiler will
> generate it.  And once the compiler has generated #2, it's a closer
> match than #1 and so will be preferred.
>

While that's clearly what the compiler did, I wasn't sure if the compiler
was correct in doing that.

Re-reading the pertinent section of the Standard this morning though, I see
that It was:

12.8 (9) says: "A user-declared copy assignment operator X::operator= is a
non-static, non-template member function of class X..."

It seems to me to follow naturally from the rule that a template constructor
is never a copy constructor, but while I've heard that rule dolled out many
times on this ng (and c.l.c++.m), I don't recall hearing the corolary about
the copy-assignment operator.

 Now I know!

-cd

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Mon, 5 Nov 2001 18:42:49 GMT
Raw View
In article <001401c1641b$56e1fcb0$0200a8c0@carl2000>, Carl Daniel
<cpdaniel@pacbell.net> writes
>I'm aware of the rule in the Standard that says that a constructor template
>is never a copy constructor, but is there any similar rule for operator=?
>So far, I haven't been able to find one.

Yes, for exactly the same reason. The compiler will generate an ordinary
member function to do copy assignment and that is necessarily a better
match than any template.


Francis Glassborow
I offer my sympathy and prayers to all those who are suffering
as a result of the events of September 11 2001.

---
[ 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.research.att.com/~austern/csc/faq.html                ]