Ho una conoscenza di base di SFINAE, ad es. come funziona enable_if
. Di recente mi sono imbattuto nello this answer e ho passato più di un'ora a cercare di capire come funziona in realtà senza alcun risultato.SFINAE Basato sull'esistenza/assenza di un membro della classe
L'obiettivo di questo codice è di sovraccaricare una funzione in base al fatto che una classe abbia un membro specifico in essa. Ecco il codice copiato, utilizza C++ 11:
template <typename T> struct Model
{
vector<T> vertices;
void transform(Matrix m)
{
for(auto &&vertex : vertices)
{
vertex.pos = m * vertex.pos;
modifyNormal(vertex, m, special_());
}
}
private:
struct general_ {};
struct special_ : general_ {};
template<typename> struct int_ { typedef int type; };
template<typename Lhs, typename Rhs,
typename int_<decltype(Lhs::normal)>::type = 0>
void modifyNormal(Lhs &&lhs, Rhs &&rhs, special_) {
lhs.normal = rhs * lhs.normal;
}
template<typename Lhs, typename Rhs>
void modifyNormal(Lhs &&lhs, Rhs &&rhs, general_) {
// do nothing
}
};
Per la vita di me, non posso avvolgere la mia testa intorno a come funziona questo meccanismo. Nello specifico, cosa ci aiuta a fare typename int_<decltype(Lhs::normal)>::type = 0
e perché abbiamo bisogno di un tipo aggiuntivo (special_
/general_
) in questo metodo.
Per me sembra che l'esempio non sia valido; il riferimento di inoltro non attiva 'decltype (Lhs :: normal)' se 'Lhs' è un lvalue. Dovrebbe essere 'decltype (std :: declval() .normal)' –
@PiotrSkotnicki L'esempio esegue, l'ho provato. – Phonon
Compila, ma hai controllato se dà un risultato corretto? –