Próbuję zdefiniować funkcję za pomocą szablonów i chcę, aby nazwa typu była int lub anEnum (określony wyliczenie, które zdefiniowałem). Próbowałem następujące, ale nie powiodło się:
template <int | anEnum T> // or <int T, anEnum T> or <int, anEnum T>
bool isFunction(const T &aVariable){}
Staram się używać szablonów zamiast definiować dwie przeciążone funkcje. Wolałbym, aby funkcja była wywoływana w następujący sposób, bez konieczności rozważania typu przez programistę
isFunction(aVariable) // and not isFunction<int> (aVariable) nor isFunction<anEnum> (aVariable)
Zasadniczo chcę, aby ta funkcja była szablonowana dla typów int i aNum. Szukałem tego, ale nie mogłem znaleźć odpowiedzi. Czego mi brakuje? Dziękuję Ci,
false
do innych typów, czy nie chcesz tworzyć instancji funkcji dla innych typów?Odpowiedzi:
Oprócz odpowiedzi w języku innym niż C ++ 20, jeśli przypadkiem jesteś w stanie użyć C ++ 20 i jego
concepts
funkcji, proponuję ci następującą implementację:Próbny
AKTUALIZACJA
Według komentarza @RichardSmith , oto bardziej skalowalne i wielokrotnego użytku podejście:
źródło
template<typename T, typename ...U> concept one_of = (std::is_same_v<T, U> || ...);
template<one_of<int, MyEnum> T> bool isFunction(T const& aVariable) {
Istnieje kilka sposobów na osiągnięcie tego. Wszystkie wymagają użycia
type_traits
nagłówka. Możesz na przykład statycznie potwierdzić dane typy w treści funkcji.Lub, jeśli trzeba rozważyć tę funkcję wśród innych przeciążeń, można zastosować technikę SFINAE.
Spowoduje to usunięcie funkcji z zestawu przeciążenia przed jej wywołaniem, jeśli typy nie będą pasować. Ale jeśli nie potrzebujesz tego zachowania, statyczne potwierdzenie pozwala na komunikat o błędzie bardziej przyjazny dla programisty.
źródło
Co z tym rozwiązaniem? Kod z funkcją zostanie skompilowany, jeśli typ T spełni twoje wymagania. W przeciwnym razie statyczne potwierdzenie nie powiedzie się.
źródło
isFunction(std::string_view)
). Podpis będzie nadal prawidłowym dopasowaniem, ale tworzenie wystąpień powoduje błąd.Poprawiłem https://stackoverflow.com/a/60271100/12894563 odpowiedź. „Jeśli constexpr” może pomóc w tej sytuacji:
isFunction (1L) zawiedzie, ponieważ nie ma przeciążonej funkcji lub gałęzi „if constexpr”.
AKTUALIZACJA: Naprawiono brakujące
https://godbolt.org/z/eh4pVn
źródło
static_assert(false, ...)
jest źle sformułowanym NDR, nawet go nie używam. Jeśli masz szczęście, twój kompilator od razu ci powie, podobnie jak Clang, godbolt.org/z/m_Gk9n