Nested template specialization
This is a MIME GnuPG-signed message. If you see this text, it means that
your E-mail or Usenet software does not support MIME signed messages.
The Internet standard for MIME PGP messages, RFC 2015, was published in 1996.
To open this message correctly you will need to install E-mail or Usenet
software that supports modern Internet standards.
--=_mimegpg-commodore.email-scan.com-5941-1264387969-0001
Content-Type: text/plain; format=flowed; charset=utf-8
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
I've been trying to figure out how to take a class template that takes on=
e
template class parameter, that defines an inner member template class, th=
at
also one class parameter; then specialization the inner member template
class whose template class parameter is the same as the outer template
class's class parameter.
After failing to figure out how to do it directly, I came up with a
circuitous workaround, but can't help but to think that there has to be a
better way. But first, here's what I started with:
template<typename outer_type>
class Outer {
public:
=09template<typename inner_type>
=09class Inner {
=09=09// =E2=80=A6
=09};
=09// =E2=80=A6
};
So, I'm trying to figure out how to define a specialization for
Inner<outer_type>. That is, a specialization for Inner with the same
typename as its Outer's typename. That is, a specialization for
Outer<int>::Inner<int>, Outer<classname>::Inner<classname>, etc=E2=80=A6
g++ appears to compile the following syntax:
template<>
template<typename common_type>
class Outer<common_type>::Inner<common_type> {
// =E2=80=A6
};
Yet, it didn't work for me. The following complete example results in the
generic template getting instantiated, and the same output from both
typeid::name() going to std::cout:
==========================
==========================
========================
#include <iostream>
#include <typeinfo>
template<typename outer_type>
class Outer {
public:
=09template<typename inner_type>
=09class Inner {
=09public:
=09=09Inner()
=09=09{
=09=09=09std::cout << "Generic template"
=09=09=09=09 << std::endl;
=09=09=09std::cout << typeid(outer_type).name() << std::endl;
=09=09=09std::cout << typeid(inner_type).name() << std::endl;
=09=09}
=09=09~Inner()
=09=09{
=09=09}
=09};
};
template<>
template<typename common_type>
class Outer<common_type>::Inner<common_type> {
public:
=09Inner()
=09{
=09=09std::cout << "Specialized" << std::endl;
=09}
=09~Inner()
=09{
=09}
};
class C {
};
int main()
{
=09Outer<C>::Inner<C> n;
}
==========================
==========================
========================
So, after beating my head against the wall, I finally came up with the
following solution that solves my immediate problem:
==========================
==========================
=========================
#include <iostream>
#include <typeinfo>
template<typename outer_type,
=09 typename inner_type> class OuterInner {
public:
=09OuterInner()
=09{
=09=09std::cout << "Generic template"
=09=09=09 << std::endl;
=09=09std::cout << typeid(outer_type).name() << std::endl;
=09=09std::cout << typeid(inner_type).name() << std::endl;
=09}
=09~OuterInner()
=09{
=09}
};
template<>
template<typename common_type>
class OuterInner<common_type, common_type> {
public:
=09OuterInner()
=09{
=09=09std::cout << "Specialized" << std::endl;
=09}
=09~OuterInner()
=09{
=09}
};
template<typename outer_type>
class Outer {
public:
=09template<typename inner_type>
=09class Inner : public OuterInner<outer_type, inner_type> {
=09public:
=09=09Inner()
=09=09{
=09=09}
=09=09~Inner()
=09=09{
=09=09}
=09};
};
class C {
};
int main()
{
=09Outer<C>::Inner<C> n;
}
==========================
==========================
=========================
I'd really like to get rid of this extra inheritance, since it complicate=
s
my overall class structure (the above is a minimalized example), and this
means that I'll have to start friending a bunch of stuff, which I'd rathe=
r
avoid doing.
--=_mimegpg-commodore.email-scan.com-5941-1264387969-0001
Content-Type: application/pgp-signature
Content-Transfer-Encoding: 7bit
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
iEYEABECAAYFAktdB4EACgkQx9p3GYHlUOIeowCfdzSexUlhx/N9F2ylACBc4iuI
xDYAnixFROgZ3Y92xA4s/UgDtOcBz2LF
=kbbw
-----END PGP SIGNATURE-----
--=_mimegpg-commodore.email-scan.com-5941-1264387969-0001--