Here is a useful example of non-integral template parameters. Some predeclarations (not all, but just enough to get the idea):
template <bool flag, class T, class F> struct SelectType
{
typedef T Result;
};
template <class T, class F> struct SelectType<false, T, F>
{
typedef F Result;
};
#define PARAMETER( selector, type ) typename SelectType<TypeTraits<T>::selector, type,
#define PTR_TRAITS typename ::Linderdaum::Utils::TypeTraits<T>::PointeeType
#define REF_TRAITS typename ::Linderdaum::Utils::TypeTraits<T>::ReferredType
using namespace ::Linderdaum::Utils;
template <class T> struct ParameterType
{
typedef
PARAMETER( IsString, clStringParameter )
PARAMETER( IsReference, clPODParameter<REF_TRAITS> )
PARAMETER( IsPointer, clPointerParameter<PTR_TRAITS> )
PARAMETER( IsFundamental, clPODParameter<T> )
// default
clPODParameter<T>
>::Result
>::Result
>::Result
>::Result
Type;
};
And the actual usage code:
clParametersList Params;
ParameterType<const LString& >::Type Param0;
ParameterType<size_t >::Type Param1;
ParameterType<clDownloadCompleteCallback >::Type Param2;
Param0.ReadValue( &P0 );
Param1.ReadValue( &P1 );
Param2.ReadValue( &P2 );
Params.push_back( &Param0 );
Params.push_back( &Param1 );
Params.push_back( &Param2 );