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:
template<typename inner_type>
class Inner {
// …
};
// …
};
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…
g++ appears to compile the following syntax:
template<>
template<typename common_type>
class Outer<common_type>::Inner<common_type> {
// …
};
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:
template<typename inner_type>
class Inner {
public:
Inner()
{
std::cout << "Generic template"
<< std::endl;
std::cout << typeid(outer_type).name() << std::endl;
std::cout << typeid(inner_type).name() << std::endl;
}
~Inner()
{
}
};
};
template<>
template<typename common_type>
class Outer<common_type>::Inner<common_type> {
public:
Inner()
{
std::cout << "Specialized" << std::endl;
}
~Inner()
{
}
};
class C {
};
int main()
{
Outer<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,
typename inner_type> class OuterInner {
public:
OuterInner()
{
std::cout << "Generic template"
<< std::endl;
std::cout << typeid(outer_type).name() << std::endl;
std::cout << typeid(inner_type).name() << std::endl;
}
~OuterInner()
{
}
};
template<>
template<typename common_type>
class OuterInner<common_type, common_type> {
public:
OuterInner()
{
std::cout << "Specialized" << std::endl;
}
~OuterInner()
{
}
};
template<typename outer_type>
class Outer {
public:
template<typename inner_type>
class Inner : public OuterInner<outer_type, inner_type> {
public:
Inner()
{
}
~Inner()
{
}
};
};
class C {
};
int main()
{
Outer<C>::Inner<C> n;
}
===========================================================================
I'd really like to get rid of this extra inheritance, since it complicates
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 rather
avoid doing.