J'ai un modèle de fonction qui prend de nombreux types différents en entrée. Parmi ces types, un seul a une getInt()
fonction. Par conséquent, je veux que le code exécute la fonction uniquement pour ce type. Veuillez suggérer une solution. Merci
#include <type_traits>
#include <typeinfo>
class X {
public:
int getInt(){
return 9;
}
};
class Y{
};
template<typename T>
void f(T& v){
// error: 'class Y' has no member named 'getInt'
// also tried std::is_same<T, X>::value
if(typeid(T).name() == typeid(X).name()){
int i = v.getInt();// I want this to be called for X only
}
}
int main(){
Y y;
f(y);
}
type_info
structure a un opérateur de comparaison d'égalité , donctypeid(T) == typeid(X)
devrait également fonctionner.if constexpr
avec conditionis_same_v<T,X>
.getInt
membre appelable . Il doit y avoir pas mal de questions ici sur stackoverflow.com uniquement sur la façon de voir si une structure ou une classe a une fonction membre spécifique, si vous recherchez un peu.Réponses:
Si vous voulez pouvoir appeler une fonction
f
pour tous les types qui ont un membre de fonctiongetInt
, pas seulementX
, vous pouvez déclarer 2 surcharges pour la fonctionf
:pour les types qui ont une
getInt
fonction membre, y compris la classeX
pour tous les autres types, y compris la classe
Y
.Solution C ++ 11 / C ++ 17
Cela dit, vous pouvez faire quelque chose comme ceci:
Découvrez-le en direct .
Veuillez noter que
std::void_t
c'est introduit dans C ++ 17, mais si vous êtes limité à C ++ 11, il est vraiment facile à implémentervoid_t
par vous-même:Et voici la version C ++ 11 en direct .
Qu'avons-nous en C ++ 20?
C ++ 20 apporte beaucoup de bonnes choses et l'une d'elles est les concepts . Ce qui est valable ci-dessus pour C ++ 11 / C ++ 14 / C ++ 17 peut être considérablement réduit en C ++ 20:
Découvrez-le en direct .
la source
void_t
cause des problèmes à un ancien compilateur (comme indiqué par le lien).template<typename T> concept HasGetInt = requires (T& v) { {v.getInt()} -> std::convertible_to<int>; };
Vous pouvez utiliser à
if constexpr
partir de C ++ 17:Avant, vous devrez utiliser des surcharges et SFINAE ou la répartition des balises.
la source
if constexpr
est une fonctionnalité C ++ 17.X
Restez simple et surchargé. A travaillé depuis au moins C ++ 98 ...
Cela suffit s'il n'y a qu'un seul type avec
getInt
fonction. S'il y a plus, ce n'est plus si simple. Il y a plusieurs façons de le faire, en voici une:Exemple en direct avec sortie de diagnostic.
la source
X
), mais, s'il y avait plus de types similaires avec un membregetInt
à l'avenir, ce n'est pas une bonne pratique. Vous voulez probablement noter que