Jump to content

Talk:Curiously recurring template pattern

Page contents not supported in other languages.
From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by 134.157.2.48 (talk) at 12:41, 15 June 2010 (About static polymorphism). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
WikiProject iconComputer science Start‑class Low‑importance
WikiProject iconThis article is within the scope of WikiProject Computer science, a collaborative effort to improve the coverage of Computer science related articles on Wikipedia. If you would like to participate, please visit the project page, where you can join the discussion and see a list of open tasks.
StartThis article has been rated as Start-class on Wikipedia's content assessment scale.
LowThis article has been rated as Low-importance on the project's importance scale.
Things you can help WikiProject Computer science with:

WikiProject iconC/C++ Unassessed Low‑importance
WikiProject iconThis article is within the scope of WikiProject C/C++, a collaborative effort to improve the coverage of C and C++ topics on Wikipedia. If you would like to participate, please visit the project page, where you can join the discussion and see a list of open tasks.
???This article has not yet received a rating on Wikipedia's content assessment scale.
LowThis article has been rated as Low-importance on the importance scale.


There's a Java version, too

Since Java 1.5 introduced its own implementation of generics, I've noticed a "curiously recurring generics pattern" in Java, but generally geared toward a somewhat different purpose:

 public interface Base<D extends Base<D>> {
     public D someOperation ();
     public D somethingElse (D argument);
     public void doSomethingWith (D whatever);
 }

It's even more common with abstract classes that provide a skeleton implementation, e.g.

 public abstract class Vector<D extends Vector<D>> {
     public abstract int getDimensions();
     private void checkDimensions (D other) {
         if (getDimensions() != other.getDimensions()) throw new Exception();
     }
     public D add (D other) {
         checkDimensions(other);
         return addImpl (other);
     }
     public D subtract (D other) {
         checkDimensions(other);
         return addImpl(other.negated());
     }
     public abstract D addImpl (D other);
     public abstract D negated ();
 }

where subclasses just override addImpl (and don't have to do dimension-mismatch detection) and implement negation. The use of the derived type as a parameter for the base type allows several Vector classes to share this code (don't repeat yourself is observed for things they can all do in a common way) while still accepting and returning themselves instead of some abstract type. Prior to Java 5, the pattern couldn't be used and all Vector subclasses would have to return a generic Vector and cope with a generic Vector parameter. So a Vector that was actually a polynomial function, FFT object, or whatever and another that was a plain old coordinate vector could be added with only a run-time ClassCastException to indicate there was a problem, and callers had to cast the return values. Java 5's covariant return types address the latter problem and its generics, coupled with the curiously recurring generics pattern, address the former problem.

(Polynomials, FFTs, and coordinate vectors can, mind you, be abstracted as having an array of components, perhaps in a java.util.Vector, of some length, added componentwise, but the example base class above is superior if you want addable, negatable things that don't have components -- either they don't decompose easily or naturally or they're actually the scalars used to build coordinate vectors -- or sparse representations etc.; FFTs *must* have a sparse representation of some sort, since you can't store the infinitely many coordinates needed for every sub and superharmonic of the fundamental.) —The preceding unsigned comment was added by 74.104.131.76 (talk) 02:21, 2 January 2007 (UTC).[reply]

Question about static polymorphism

I wonder if it can really be called "polymorphism", because two subclasses will inherit from two different superclass :

 struct Derived1 : Base<Derived1>
   {...};
 struct Derived2 : Base<Derived2>
   {...};

The two superclasses are of different types from the point of vew of the compiler. I may not see the true trick behind, but I don't understand how it can be used to emulate polymorphism... Maybe an example of exploitation would be welcome.