Topic: specialization and derivation
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/07/07 Raw View
Siemel Naran wrote:
>
> On 28 May 99 07:55:27 GMT, Olaf Luethje <luethje@ert.rwth-aachen.de> wrote:
>
> >class A {};
> >class B: A {};
> >
> >template <class T>
> >void f(T t) { cout << "general" << endl; }
> >
> >template<>
> >void f<A*>(A *t) { cout << "special" << endl; }
> >
> >int main()
> >{
> > B b;
> > f(b);
> >}
> >
> >The output is 'general'. Or is my compiler just not uptodate?
> >I would favor a behaviour that first looks for a specialization to B
> >itself and then - if there is no such thing - looks for specializations
> >to base classes of B, finding f<A>.
>
> Your compiler is right. The compiler cannot do any conversions on a
> template argument as the exact match is available. Hence f(3) calls
> f<int>(int), not f<double>(double) after converting (int)3 to
> (double)3.0. And f(&b) calls f<B*>(B*), not f<A*>(A*) after converting
> B* to A*.
>
> One solution is to write a function f for each class B derived from A.
> template <> void f<B1*>(B1 * t) { return f<A*>(static_cast<A*>(t)); }
> template <> void f<B2*>(B2 * t) { return f<A*>(static_cast<A*>(t)); }
>
> Another solution is to change how you call the function
> f(static_cast<A*>(&b));
>
> Another solution is to give class A a non-virtual inline member function
> base(), and call your function as.
> f(b.base());
Yet another solution it to just tell the compiler which template
arguments to use:
f<A*>(&b);
If you want to automate this (specialize for "pointer to derived
from A"), the following machinery should work (but I haven't
tested it):
class A {};
class B: public A {};
struct pointer_to_derived_from_A {};
struct not_pointer_to_derived_from_A {};
inline pointer_to_derived_from_A f_helper(A**)
{
return pointer_to_derived_from_A();
}
inline not_pointer_to_derived_from_A f_helper(void*)
{
return not_pointer_to_derived_from_A;
}
template<class T>
void f(T t, not_pointer_to_derived_from_A)
{
cout << "general" << endl;
}
void f(A* pA, pointer_to_derived_from_A)
{
cout << "special" << endl;
}
template<class T>
inline void f(T t)
{
f(t, f_helper(&t));
}
int main()
{
B b;
f(&b);
}
This calls f<B*>(&b), which in turn calls f(t, f_helper(&t))
(where t is &b). Overload resolution will AFAIK prefer
f_helper(A**) to f_helper(void*), and since the return
type of f_helper(A**) is pointer_to_derived_from_A,
f(A*, pointer_to_derived_from_A) is called.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Olaf Luethje <luethje@ert.rwth-aachen.de>
Date: 1999/06/07 Raw View
This is a multi-part message in MIME format.
--------------9032DC0F8059C4509357E27B
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
James Kuyper wrote:
> You didn't specialize f<A>. You specialized f<A*>. You didn't call
> f(&b), you called f(b), so your specialization couldn't possibly apply.
> ---
Ok, your right. That mistake must have happened when I changed my testprogram
in order to try specializing to pointers to A, but as Siemel said, the problem
still
remains.
---
--------------9032DC0F8059C4509357E27B
Content-Type: text/x-vcard; charset=us-ascii;
name="luethje.vcf"
Content-Description: Card for Olaf Luethje
Content-Disposition: attachment;
filename="luethje.vcf"
Content-Transfer-Encoding: quoted-printable
X-MIME-Autoconverted: from 8bit to quoted-printable by ncar.UCAR.EDU id JAA17281
begin:vcard=20
n:L=FCthje;Olaf
tel;fax:+49 - 241 - 8888195
tel;home:+49 - 241 - 5153509
tel;work:+49 - 241 - 80 7887
x-mozilla-html:TRUE
org:RWTH Aachen, ISS - 611810
version:2.1
email;internet:luethje@ert.rwth-aachen.de
title:Dipl.-Ing.
adr;quoted-printable:;;ISS-611810=3D0D=3D0ATemplergraben 55;Aachen;;52056=
;Germany
x-mozilla-cpt:;17984
fn:Olaf L=FCthje
end:vcard
--------------9032DC0F8059C4509357E27B--
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1999/05/29 Raw View
Olaf Luethje wrote:
OL>
OL> I don't see why specialized templates to a base class do not apply to
OL> the derived classes (unless there is a specialization to the derived
OL> class), just as in this little program:
OL>
OL> #include <iostream.h>
OL>
OL> class A
OL> {};
OL>
OL> class B: A
OL> {};
OL>
OL> template <class T>
OL> void f(T t)
OL> {
OL> cout << "general" << endl;
OL> }
OL>
OL> template<>
OL> void f<A*>(A *t)
OL> {
OL> cout << "special" << endl;
OL> }
OL>
OL> int main()
OL> {
OL> B b;
OL> f(b);
OL> }
OL>
OL> The output is 'general'. Or is my compiler just not uptodate?
OL> I would favor a behaviour that first looks for a specialization to B
OL> itself and then - if there is no such thing - looks for specializations
OL> to base classes of B, finding f<A>.
You didn't specialize f<A>. You specialized f<A*>. You didn't call
f(&b), you called f(b), so your specialization couldn't possibly apply.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: sbnaran@fermi.ceg.uiuc.edu (Siemel Naran)
Date: 1999/05/30 Raw View
On 29 May 99 17:15:18 GMT, James Kuyper <kuyper@wizard.net> wrote:
>Olaf Luethje wrote:
>You didn't specialize f<A>. You specialized f<A*>. You didn't call
>f(&b), you called f(b), so your specialization couldn't possibly apply.
Fine. But please extend your post. Even if Olaf wrote f(&b), then
the compiler would still call f<B*>, not f<A*>. Or if Olaf specialized
f<A>, then f(b) would still call f<B>.
--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Olaf Luethje <luethje@ert.rwth-aachen.de>
Date: 1999/05/28 Raw View
This is a multi-part message in MIME format.
--------------ED501C024E54BBE3B98C8C1A
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
I don't see why specialized templates to a base class do not apply to
the derived classes (unless there is a specialization to the derived
class), just as in this little program:
#include <iostream.h>
class A
{};
class B: A
{};
template <class T>
void f(T t)
{
cout << "general" << endl;
}
template<>
void f<A*>(A *t)
{
cout << "special" << endl;
}
int main()
{
B b;
f(b);
}
The output is 'general'. Or is my compiler just not uptodate?
I would favor a behaviour that first looks for a specialization to B
itself and then - if there is no such thing - looks for specializations
to base classes of B, finding f<A>.
--------------ED501C024E54BBE3B98C8C1A
Content-Type: text/x-vcard; charset=us-ascii;
name="luethje.vcf"
Content-Description: Card for Olaf Luethje
Content-Disposition: attachment;
filename="luethje.vcf"
Content-Transfer-Encoding: quoted-printable
X-MIME-Autoconverted: from 8bit to quoted-printable by ncar.UCAR.EDU id GAA11934
begin:vcard=20
n:L=FCthje;Olaf
tel;fax:+49 - 241 - 8888195
tel;home:+49 - 241 - 5153509
tel;work:+49 - 241 - 80 7887
x-mozilla-html:TRUE
org:RWTH Aachen, ISS - 611810
version:2.1
email;internet:luethje@ert.rwth-aachen.de
title:Dipl.-Ing.
adr;quoted-printable:;;ISS-611810=3D0D=3D0ATemplergraben 55;Aachen;;52056=
;Germany
x-mozilla-cpt:;17984
fn:Olaf L=FCthje
end:vcard
--------------ED501C024E54BBE3B98C8C1A--
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: sbnaran@localhost.localdomain (Siemel Naran)
Date: 1999/05/28 Raw View
On 28 May 99 07:55:27 GMT, Olaf Luethje <luethje@ert.rwth-aachen.de> wrote:
>class A {};
>class B: A {};
>
>template <class T>
>void f(T t) { cout << "general" << endl; }
>
>template<>
>void f<A*>(A *t) { cout << "special" << endl; }
>
>int main()
>{
> B b;
> f(b);
>}
>
>The output is 'general'. Or is my compiler just not uptodate?
>I would favor a behaviour that first looks for a specialization to B
>itself and then - if there is no such thing - looks for specializations
>to base classes of B, finding f<A>.
Your compiler is right. The compiler cannot do any conversions on a
template argument as the exact match is available. Hence f(3) calls
f<int>(int), not f<double>(double) after converting (int)3 to
(double)3.0. And f(&b) calls f<B*>(B*), not f<A*>(A*) after converting
B* to A*.
One solution is to write a function f for each class B derived from A.
template <> void f<B1*>(B1 * t) { return f<A*>(static_cast<A*>(t)); }
template <> void f<B2*>(B2 * t) { return f<A*>(static_cast<A*>(t)); }
Another solution is to change how you call the function
f(static_cast<A*>(&b));
Another solution is to give class A a non-virtual inline member function
base(), and call your function as.
f(b.base());
--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]