#include <iostream>
template< typename PParameter00 = void, typename PParameter01 = void, typename PParameter02 = void, typename PParameter03 = void >
struct TIdentityParameter // Users need to inherit from it. Add more types as needed.
{
typedef PParameter00 TType00;
typedef PParameter01 TType01;
typedef PParameter02 TType02;
typedef PParameter03 TType03;
};
struct TUserFunctor00 : public TIdentityParameter< float const &, int, void * >
{
void operator()(float const &, int, void *);
// or they can do
//void operator()(TType00, TType01, TType02);
};
struct TUserFunctor01 : public TIdentityParameter< char const *, double >
{
void operator()(char const*, double);
// or they can do
//void operator()(TType00, TType01);
};
template< bool pValue >
struct TValueBool
{
static bool const sValue = pValue;
};
template< typename PType00, typename PType01 >
struct TIsSame : public TValueBool<false>
{
};
template< typename PType >
struct TIsSame< PType, PType > : public TValueBool<true>
{
};
int main(void)
{
std::cout << TIsSame< TUserFunctor00::TType02, void * >::sValue << std::endl;
std::cout << TIsSame< TUserFunctor01::TType00, double >::sValue << std::endl;
return (0);
}
Code on [ideone][1]. I don't think it's asking too much from users to inherit from your struct in a pattern explained to them. After all, they want to work with your library. Anyway, maybe it's not what you are looking for.
+++++++++++++++++++++++++++++++++++++++++++ +++++++
EDIT: Ecco qualcosa, forse, un po 'più vicino alla funzionalità che JAred sta cercando, ma, ho capito, lo stile non lo attrae. Sebbene, all'interno di C++ 03, non vedo come si possa fare diversamente. Nota, puoi prendere TIdentityParameter
prendere, diciamo 16 argomenti del template per coprire 16 possibili tipi. Ancora una volta, sì, l'utente deve ereditare e specificare i tipi. Ideone:
#include <iostream>
struct TOneCrazyStruct
{
};
template< typename PParameter00 = TOneCrazyStruct, typename PParameter01 = TOneCrazyStruct, typename PParameter02 = TOneCrazyStruct,
typename PParameter03 = TOneCrazyStruct, typename PParameter04 = TOneCrazyStruct >
struct TIdentityParameter //Users will need to inherit from this struct as shown below.
{
typedef PParameter00 TType00;
typedef PParameter01 TType01;
typedef PParameter02 TType02;
typedef PParameter03 TType03;
typedef PParameter04 TType04;
};
struct TUserFunctor00 : public TIdentityParameter< float const &, int, void *, double >
{
void operator()(float const &, int, void *);
void operator()(double);
};
template< bool pValue >
struct TValueBool
{
static bool const sValue = pValue;
};
template< typename PType00, typename PType01 >
struct TIsSame : public TValueBool<false>
{
};
template< typename PType >
struct TIsSame< PType, PType > : public TValueBool<true>
{
};
template< typename PFunctor, typename PParameter >
struct THasType : public TValueBool<
TIsSame< typename PFunctor::TType00, PParameter >::sValue || TIsSame< typename PFunctor::TType01, PParameter >::sValue
|| TIsSame< typename PFunctor::TType02, PParameter >::sValue || TIsSame< typename PFunctor::TType03, PParameter >::sValue >
{
};
int main(void)
{
std::cout << THasType< TUserFunctor00, void * >::sValue << std::endl;
std::cout << THasType< TUserFunctor00, long double >::sValue << std::endl;
return (0);
}
Non puoi semplicemente aggiungere lo stesso 'typedef' all'interno di ogni functor? Qualcosa come 'typedef float const e TParameter;' all'interno di 'takes_float_cref' e quindi testare per' Functor :: TParameter'? – lapk
@AxxA, grazie per il suggerimento. Sì, questa è una soluzione, ma trovo pesante da richiedere quella dei clienti. Non sono sicuro che sarebbe in grado di adattarsi bene al caso generale dei parametri N. –
Beh, in realtà potrebbe non essere poi così male. È troppo lungo da scrivere qui, lo posterò come risposta. Vedi se ti aiuta. – lapk