I'm trying to write a variation of the template class defining a super type idiom. The class Inherit introduces the type Super to denote the possibly very long super type, and also needs to know the derived type New to do some extra things which I'm not showing here.
This works fine if the type passed to New is not a template, but fails with templates. Here is a full example compiled with clang++-3.8 -std=c++1y -Wall (gcc gives the same output):
struct SomeBase {};
template<class New, class Base>
struct Inherit : Base {
using Super = Inherit<New, Base>;
};
struct NonTemplate : Inherit<NonTemplate, SomeBase> {
using X = Super;
// compiles and is nice and short
};
template<class T>
struct Template : Inherit<Template<T>, SomeBase>
{
using A = Super;
// error: unknown type name 'Super'; did you mean 'NonTemplate::Super'?
using B = typename Super;
// error: expected a qualified name after 'typename'
using C = Inherit::Super;
// error: 'Inherit' is not a class, namespace, or enumeration
using D = typename Inherit<Template<T>, SomeBase>::Super;
// compiles, but what's the point?
};
int main() {
return 0;
}
If I didn't need the New parameter I am also able to use Inherit with templates, but I really need New. I could make the code compile by using option D but that defeats the whole purpose.
I have two questions:
- What exactly is the language issue which prevents the type name
Superfrom being known inside the classTemplateand why is that different in theNonTemplatecase? - Does anyone have an idea for a good solution to this problem?