Mam szablon funkcji, który pobiera wiele różnych typów podczas wprowadzania. Spośród tych typów tylko jeden z nich ma getInt()
funkcję. Dlatego chcę, aby kod uruchamiał funkcję tylko dla tego typu. Proszę zaproponować rozwiązanie. Dzięki
#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
struktura ma operator porównania równości , więc teżtypeid(T) == typeid(X)
powinien działać.if constexpr
z warunkiemis_same_v<T,X>
.getInt
. Na stackoverflow.com musi być sporo pytań o to, jak sprawdzić, czy struktura lub klasa ma określoną funkcję członka, jeśli tylko trochę przeszukasz.Odpowiedzi:
Jeśli chcesz mieć możliwość wywołania funkcji
f
dla wszystkich typów, które mają element członkowski funkcjigetInt
, nie tylkoX
, możesz zadeklarować 2 przeciążenia funkcjif
:dla typów, które mają
getInt
funkcję członka, w tym klasęX
dla wszystkich innych typów, w tym klasy
Y
.Rozwiązanie C ++ 11 / C ++ 17
Mając to na uwadze, możesz zrobić coś takiego:
Sprawdź to na żywo .
Należy pamiętać, że
std::void_t
został wprowadzony w C ++ 17, ale jeśli jesteś ograniczony do C ++ 11, to naprawdę jest bardzo łatwe do samodzielnego wdrożeniavoid_t
:A oto wersja C ++ 11 na żywo .
Co mamy w C ++ 20?
C ++ 20 przynosi wiele dobrych rzeczy, a jedną z nich są koncepcje . Przede wszystkim, co jest ważne dla C ++ 11 / C ++ 14 / C ++ 17, można znacznie zmniejszyć w C ++ 20:
Sprawdź to na żywo .
źródło
void_t
powoduje problemy w starym kompilatorze (jak wskazuje link).template<typename T> concept HasGetInt = requires (T& v) { {v.getInt()} -> std::convertible_to<int>; };
Możesz użyć
if constexpr
z C ++ 17:Wcześniej będziesz musiał używać przeciążeń i SFINAE lub wysyłania tagów.
źródło
if constexpr
jest funkcją C ++ 17.X
Prostota i przeciążenie. Pracuje od co najmniej C ++ 98 ...
To wystarczy, jeśli istnieje tylko jeden typ z
getInt
funkcją. Jeśli jest więcej, nie jest to już takie proste. Jest na to kilka sposobów, oto jeden:Przykład na żywo z wyjściem diagnostycznym.
źródło
X
), ale jeśligetInt
w przyszłości będzie więcej podobnych typów z elementem, nie jest to taka dobra praktyka. Prawdopodobnie chcesz to zauważyć