/ / Specializzazione dei modelli con più modelli variadici - c ++, modelli, c ++ 11, typetraits

Specializzazione dei modelli con più modelli variadici - c ++, templates, c ++ 11, typetraits

Nel mio ultima domanda Ho ricevuto un grande aiuto per far funzionare una specializzazione di template. Ora ho bisogno di una piccola estensione. Voglio due specializzazioni per queste affermazioni:

int main()
{
// First specialization
holder_ext<person> h1;
holder_ext<person, &person::age> h2;
holder_ext<int> h3;

// Second specialization
holder_ext<person, &person::age, &person::name> h4;
}

La mia persona di classe si presenta così:

class person
{
private:
std::string name_;
int age_;
public:
person(const std::string &name)
: name_(name), age_(56)
{}
void age(int a) { age_ = i; }
void name(const std::string &n) { name_ = n; }
};

La cosa speciale è che i due membrile funzioni hanno diversi tipi di parametri. Quindi non posso usare la stessa funzione membro del modello variadic per entrambi. L'ho provato con due diversi modelli variadic. Ma questo non funziona. Anche i valori predefiniti per le funzioni membro non funzionano.

Qualcuno ha un buon suggerimento per me?

Questa è la soluzione con una funzione membro (grazie a pubby):

template < class T, void (std::conditional<std::is_class<T>::value, T, struct dummy>::type::* ...FUNC)(int)> class holder;

template < class T, void (T::*FUNC)(int)>
class holder<T, FUNC>
{
public:
explicit holder() : setter(FUNC) { std::cout << "funcn"; }
private:
std::function<void (value_type&, int)> setter;
};

template < class T>
class holder<T>
{
public:
explicit holder() { std::cout << "plainn"; }
};

Grazie ancora in anticipo!

P.S .: E no, non uscirò tra due giorni con "cosa deve fare con tre, quattro, cinque funzioni membro"? ;-)

risposte:

0 per risposta № 1

Per una soluzione completamente generica che dovresti colpireun problema che non può essere risolto: il tipo di argomento del modello non di tipo non può essere dedotto, quindi deve essere esplicito nella dichiarazione del modello, quindi non c'è modo di dire al modello che si desidera più argomenti da puntatore a membro ciascuno di che avrà un tipo ancora sconosciuto.

Non ho mai giocato abbastanza con C ++ 11, ma potresti provare a forzare un ordinamento sugli argomenti del modello membro e fornire tutte le firme nel modello:

template <typename T,
void (std::conditional<...>::type*)(int),
void (std::conditional<...>::type*)(const std::string&)>

Ancora una volta, potrebbe funzionare o potrebbe non ...


0 per risposta № 2

Finalmente ho trovato una soluzione al mio problema. È un mix tra template variadici e specilization template:

template < class T,
void (std::conditional<std::is_base_of<object, T>::value, T, struct dummy>::type::*FUNC1)(int) = nullptr,
void (std::conditional<std::is_base_of<object, T>::value, T, struct dummy>::type::* ...FUNC2)(const std::string&)
>
class holder_ext;

template < class T,
void (std::conditional<std::is_base_of<object, T>::value, T, struct dummy>::type::*FUNC1)(int),
void (std::conditional<std::is_base_of<object, T>::value, T, struct dummy>::type::*FUNC2)(const std::string&)
>
class holder_ext<T, FUNC1, FUNC2>
{
public:
holder_ext() { std::cout << "func 2 testn"; }
};

template < class T,
void (std::conditional<std::is_base_of<object, T>::value, T, struct dummy>::type::*FUNC1)(int)
>
class holder_ext<T, FUNC1>
{
public:
holder_ext() { std::cout << "func 1 testn"; }
};

Uso una dichiarazione non implementata e definisco due specializzazioni. Uno con entrambe le funzioni membro e l'altro per tutti gli altri casi.

Se esiste una soluzione migliore, non esitare a dirmelo.