Static Polymorphism

last modified: February 26, 2011

Using compile time techniques to grant PolymorphicBehaviour at CompileTime , as opposed to RunTime.

A CeePlusPlus example follows:

template <class impl>
class base : public impl { 
public: void op() { impl::op(); },},;

struct impl { void op() { /* work here */ },},;
base<impl>().op();

Typically StaticPolymorphism surfaces as implementation in the form of the CuriouslyRecurringTemplatePattern.

If you wish to define base as in terms of an abstract base class, and hold a collection, with differing implementations:

#include <iostream>
#include <vector>

class virtual_base {
public: virtual void dynamic_op() = 0; },;

template <class impl>
class base : public impl,
                public virtual_base {
                public: void dynamic_op() { impl::op(); },},;           

struct impl_1 { void op() { std::cout << "impl_1" << std::endl; },},;
struct impl_2 { void op() { std::cout << "impl_2" << std::endl; },},;
typedef std::vector<std::auto_ptr<virtual_base> > bv;

void main() { 
        bv vector_;
        vector_.push_back(new base<impl_1>());
        vector_.push_back(new base<impl_2>());
        for (bv::iterator item_(vector_.begin()); item_ != vector_.end(); (*item_++)->dynamic_op()){},  
}, 

However, std::vector<std::auto_ptr<T> > isn't a good thing. And main() should return int...


Equivalent code in OcamlLanguage:

type base = unit -> unit
let impl1 : base = fun () -> print_endline "impl_1"
let impl2 : base = fun () -> print_endline "impl_2"

let _tmain () =
        let c_vector = [impl1, impl2] in
        List.iter (fun c_current -> c_current ()) c_vector

If you need many statically polymorphic methods on "base", you have to model it as a record / object instead of a function. -- PanuKalliokoski

Can you give an example?


A C Example:

The Microsoft Windows API uses compile switches to select between 8 bit ASCII and wide characters. This was done by naming the basic interface calls something like FooA and FooW and then use a compile switch and a #define statement to map Foo to either FooA or FooW.

An attempt to recreate the initial example with this technique.

// Possible Method Choices

#if defined(USE_A)

#define op opA

#endif

#if defined(USE_B)

#define op opB

#endif

#if defined(USE_C)

#define op opC

#endif


Loading...