working on a project that relies heavily on Coplien's 'curiously recurring template' mechanism for compile-time polymorphism, I realized that all the while I had assumed that there was no way around having to tediously define each and every function in the base class (without some default action, as virtual functions can) - I was wrong!
Code:
#include <iostream>
/* a hypothetical framework */
template <class base_type>
class abstract_interface
{
public:
inline
base_type &
base(void)
{
return static_cast<base_type&>(*this);
}
inline
const base_type &
base(void) const
{
return static_cast<const base_type&>(*this);
}
template <class value_type>
inline
value_type
limit(value_type value)
{
return base().limit(value);
}
template <class value_type>
inline
value_type
normalize(value_type value)
{
return base().normalize(value);
}
};
template <class base_type>
class inherit_interface : public abstract_interface<base_type>
{
public:
template <class value_type>
inline
value_type
limit(value_type value)
{
std::cout << "limit [default]" << std::endl;
return value;
}
template <class value_type>
inline
value_type
normalize(value_type value)
{
std::cout << "normalize [default]" << std::endl;
return value;
}
};
class object : public inherit_interface<object>
{
public:
template <class value_type>
inline
value_type
normalize(value_type value)
{
std::cout << "normalize [object]" << std::endl;
return value;
}
};
template <class base_type, class value_type>
inline
value_type
normalize(abstract_interface<base_type> & lhs, value_type value)
{
return lhs.normalize(value);
}
template <class base_type, class value_type>
inline
value_type
limit(abstract_interface<base_type> & lhs, value_type value)
{
return lhs.limit(value);
}
/* a simple test driver */
int
main(void)
{
object object;
normalize(object, double());
limit(object, double());
}
abstract_interface binds the framework together, but inherit_interface transforms it into a truly 'virtual template'! I wonder if anyone else noticed this?