Ich habe eine Funktionsvorlage, die viele verschiedene Typen als Eingabe verwendet. Von diesen Typen hat nur einer eine getInt()
Funktion. Daher möchte ich, dass der Code die Funktion nur für diesen Typ ausführt. Bitte schlagen Sie eine Lösung vor. Vielen Dank
#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
Struktur verfügt über einen Gleichheitsvergleichsoperator undtypeid(T) == typeid(X)
sollte daher auch funktionieren.if constexpr
mit Bedingungis_same_v<T,X>
.getInt
Mitglied hat. Allein hier auf stackoverflow.com muss es einige Fragen geben, wie Sie feststellen können, ob eine Struktur oder Klasse eine bestimmte Elementfunktion hat, wenn Sie nur ein wenig suchen.Antworten:
Wenn Sie in der Lage sein möchten, eine Funktion
f
für alle Typen mit Funktionselement aufzurufen , können SiegetInt
nicht nurX
2 Überladungen für die Funktion deklarierenf
:für Typen mit
getInt
Elementfunktion, einschließlich KlasseX
für alle anderen Typen, einschließlich Klasse
Y
.C ++ 11 / C ++ 17-Lösung
In diesem Sinne könnten Sie so etwas tun:
Probieren Sie es live aus .
Bitte beachten Sie, dass dies
std::void_t
in C ++ 17 eingeführt wird. Wenn Sie jedoch auf C ++ 11 beschränkt sind, ist die Implementierungvoid_t
auf eigene Faust sehr einfach :Und hier ist C ++ 11 Version live .
Was haben wir in C ++ 20?
C ++ 20 bringt viele gute Dinge und eines davon sind Konzepte . Das, was für C ++ 11 / C ++ 14 / C ++ 17 gültig ist, kann in C ++ 20 erheblich reduziert werden:
Probieren Sie es live aus .
quelle
void_t
Probleme bei einigen alten Compilern (wie durch den Link angegeben).template<typename T> concept HasGetInt = requires (T& v) { {v.getInt()} -> std::convertible_to<int>; };
Sie können
if constexpr
von C ++ 17 verwenden:Zuvor müssen Sie Überladungen und SFINAE- oder Tag-Dispatching verwenden.
quelle
if constexpr
ist eine C ++ 17-Funktion.X
Halten Sie es einfach und überladen. Hat seit mindestens C ++ 98 funktioniert ...
Dies reicht aus, wenn es immer nur einen Typ mit
getInt
Funktion gibt. Wenn es mehr gibt, ist es nicht mehr so einfach. Es gibt verschiedene Möglichkeiten, hier eine:Live-Beispiel mit Diagnoseausgabe.
quelle
X
) gibt. Wenn es jedochgetInt
in Zukunft mehr ähnliche Typen mit Mitgliedern gibt , ist dies keine so gute Praxis. Sie möchten wahrscheinlich das beachten