|
Boost : |
Subject: Re: [boost] [xint] Third release is ready, requesting preliminary review
From: DE (satan66613_at_[hidden])
Date: 2010-05-04 03:58:01
on 04.05.2010 at 2:20
Chad Nelson wrote :
> Hm... I *think* I see it now. At least, some of the time I think I do.
> :-) Please check my understanding: you're suggesting that I use
> functions in base_integer to do the allocation, and have them call other
> functions in base_integer to do the things that are different between
> fixed_integer and the variable-length integers. But then override those
> functions in the fixed_integer classes, not as virtual functions, but
> using CRTP to call the overridden functions. Am I right?
let me try to explain
suppose the interface of all your concrete classes (i.e. 'integer',
'nothrow_integer' and 'fixed_integer') is homogeneous
that is all classes have identical names for respective members with
consistent semantics
then each of the classes inherits the base class
template<typename type>
class base_integer {};
in the following way
class integer : public base_integer<integer>
{/*...*/};
then you can write template functions for all types in the following
manner:
template<typename int_type>
void foo(const base_integer<int_type>&);
template<typename type1, typename type2>
void bar(const base_integer<type1>&, const base_integer<type2>&);
such functions will handle all types derived from base_integer
providing their type as template argument
an implementation of such a function can be like this:
template<typename type>
type negate(const base_integer<type> &a)
{
const type &instance = *static_cast<type*>(&a);
return instance.negated();
}
notice that this function returns a concrete type deduced
automatically
also this function implies that all concrete types have 'negated()'
member function (as an example)
also the ugly static_cast may be wrapped in a functions:
template<typename type>
type &get_instance(base_integer<type> &a) { return *static_cast<type*>(&a); }
template<typename type>
const type &get_instance(const base_integer<type> &a) { return *static_cast<const type*>(&a); }
designing a lib this way you have a header with those (CRTP'ed)
template stuff while concrete types reside in header and/or cpp file
as is convenient for you
as well this approach is type safe as long as 'base_integer'
parameterized according to the contract
please think about it, it is a very powerful design technique, also it
may solve a whole lot of troubles now and later
i like this theme very much and will happily write more words on this
on your demand
-- Pavel P.S. if you notice a grammar mistake or weird phrasing in my message please point it out
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk