edit: I\'ll put a github link here when I am done altering my design for anyone who is interested.
Background
I\'m replacing a
Another possibility (that might or might not save you keystrokes) would be not using the derived classes' nested types in the parent in some places. Eg. instead of
void foo(typename TWO::dummy & d);
you'd use
template <class T>
void foo(typename T& d);
For extra points, you could use SFINAE to actually limit T
to the types permissible for the original variant. (Note that inside nested templates, TWO::dummy
can be used freely - they are only instantiated after the whole thing incl. derived
has been, so it works out. In the naive version, derived
is still incomplete at the point of instantiating the base
with its member functions, it has no ::dummy
, which is why it fails)
Extending @jpalecek's idea, we could make that template argument take a default argument. But you need to enable C++0x to get this
#include <typeinfo>
#include <cstdio>
template<typename TWO>
class base
{
public:
template <typename X = TWO> // <-- (requires C++0x to have a default)
void foo(typename X::dummy& d)
{
printf("%s\n", typeid(d).name());
}
};
template<typename DUMMY>
class derived
: public base< derived<DUMMY> >
{
public:
typedef DUMMY dummy;
};
struct tag{};
int main()
{
derived<tag> foo;
tag t;
foo.foo(t); // <--- call the function like normal.
}
http://ideone.com/AXXdW
There's no need for the traits
class. You can just use type_key
directly in base
.
You cannot, however, avoid passing the type explicitly to base
. At the time base
is instantiated, the typedef in derived
has not yet been seen by the compiler (more exactly: the class derived
is not yet complete — how could it, given that even its base class doesn't exist yet).