TLDR: vedere l'ultimo paragrafo.enable_if type non è di una determinata classe template
Ho un operator&
definiti per diverse classi template in questo modo:
template <typename T>
struct Class {
Class(T const &t) { }
};
template <typename T_Lhs, typename T_Rhs>
struct ClassAnd {
ClassAnd(T_Lhs const &lhs, T_Rhs const &rhs) { }
};
template <typename T, typename T_Rhs>
ClassAnd<Class<T>, T_Rhs> operator&(Class<T> const &lhs, T_Rhs const &rhs) {
return ClassAnd<Class<T>, T_Rhs>(lhs, rhs);
}
template <typename T0, typename T1, typename T_Rhs>
ClassAnd<ClassAnd<T0, T1>, T_Rhs> operator&(ClassAnd<T0, T1> const &lhs, T_Rhs const &rhs) {
return ClassAnd<ClassAnd<T0, T1>, T_Rhs>(lhs, rhs);
}
int main() {
Class<int> a(42);
Class<double> b(3.14);
auto c = a & b;
}
Questo funziona bene.
Il problema si verifica quando voglio aggiungere un non funzionamento, che è consentito solo su un lato o l'altro di una e di funzionamento, e deve restituire un'istanza di ClassAndNot
piuttosto che ClassAnd
:
template <typename T>
struct ClassNot {
ClassNot(T const &t) : value(t) { }
T value;
};
template <typename T_Lhs, typename T_Rhs>
struct ClassAndNot {
ClassAndNot(T_Lhs const &lhs, T_Rhs const &rhs) { }
};
template <typename T_Lhs, typename T_Rhs>
ClassAndNot<T_Lhs, T_Rhs> operator&(T_Lhs const &lhs, ClassNot<T_Rhs> const &rhs) {
return ClassAndNot<T_Lhs, T_Rhs>(lhs, rhs.value);
}
template <typename T_Rhs>
ClassNot<T> operator!(T_Rhs const &rhs) {
return ClassNot<T_Rhs>(rhs);
}
...
auto c = a & !b;
Questo determina un'ambiguità tra lo operator&
prendendo un lato arbitrario a destra per restituire un ClassAnd
e lo operator&
prendendo un ClassNot
lato destro per restituire un ClassAndNot
.
Domanda:
Come potrebbe std::enable_if
essere utilizzato qui per disattivare il primo operator&
se il suo lato destro è di uno qualsiasi dei tipi ClassNot
? C'è qualcosa come std::is_same
che restituisce true se un lato è un'istanza di template dell'altro?
p.s. È possibile trovare un esempio funzionante completo su ideone.
Il secondo esempio è esattamente quello che stavo cercando (ma fornito dalla libreria standard). Vado con il primo esempio per mantenere le cose un po 'più semplici. Grazie! – zennehoy
@zennehoy Direi che uno dei motivi per cui non è fornito dalla libreria standard è che non esiste un modo per scriverlo completamente in generale per i modelli di classe che accettano parametri di modello non di modello o modello. – Angew