There really is no solution to this problem: you need a isSameSpecific for each instance of the template that you use. (In other words, in Foo :
template <typename T> virtual bool isSameSpecific( Qux<T>* );
is illegal, but:
virtual bool isSameSpecific( Qux<int>* ); virtual bool isSameSpecific( Qux<double>* );
no.)
You may be able to create an abstract QuxBase , and Qux<T> derives from it. Most likely, this will simply move the problem to QuxBase , but if isSameSpecific is independent of type T , for example because you can define some canonical spanning type, it can be executable. Without knowing more about Qux and isSameSpecific , it's hard to say. (If Qux<T>::isSameSpecific should always return false if the types of instances are different, for example, you can enter check QuxBase::isSameSpecific and go to another virtual function if the types are identical.)
Please note that such problems affect all alternative methods by sending multiple times. In the end, you're requesting sending through an open set of types, which means a potentially infinite number of different functions.
EDIT:
Just to be clear: I assume that your isSame is just for example, and that the actual operations may be more complex. The actual code that you show clearly falls into what I propose in the second paragraph; in fact, it can be implemented even without multiple submissions. Just define the canonical "identifier", type, define the virtual function getCanonicalIdentifier and use this in isSame :
bool Foo::isSame( Foo const* other ) const { return getCanonicalIdentifier() == other->getCanonicalIdentifier(); }
In this case, if it follows from different types that isSame returns false (often the case if isSame means that it looks like for example), you also do not need double sending:
bool Foo::isSame( Foo const* other ) const { return typeid( *this ) == typeid( *other ) && isSameSpecific( other ); }
The resulting isSameSpecific will have to convert the type to a pointer, but since it is guaranteed that it is the same as the this type, that is a simple and safe operation.
Finally: if classes do not have semantics of values (and almost certainly should not, if polymorphism is involved), something simple:
bool Foo::isSame( Foo const* other ) const { return this == other; }
may be enough.
All this applies only to something like isSame . If you have other features that are affected, you are back to what I originally said.