Jak wdrażana jest funkcja std :: is_function?

82

Jak wygląda implementacja std::is_function?

template<class T>
struct is_function : std::integral_constant<
    bool,
    !std::is_const<const T>::value && !std::is_reference<T>::value
> {};

(z referencji CPP )

Wydaje mi się, intże w tej definicji byłaby funkcja. czego mi brakuje?

Rian Quinn
źródło
10
Pomyśl o tej !is_constczęści.
aschepler
Dlaczego typy funkcji nie mogą być stałymi? Czy ma to związek z odrażającymi typami?
jtbandes
4
@ jtbandes to dlatego, że funkcje są jedną z niewielu rzeczy w C ++, które nie są obiektami.
Ayxan
1
Chyba dlatego, że w pewnym sensie zawsze tak jest
RiaD
Wydaje mi się, że tytuł wprowadza w błąd. „Jak to jest poprawna implementacja std :: is_function?” wydaje się bardziej odpowiednie.
val mówi Przywróć Monikę

Odpowiedzi:

73

Omówmy warunki, jakie się pojawiają:
Jeśli const Tnie jest const ( consttak naprawdę nie ma zastosowania do typów funkcji, ponieważ funkcje nie są obiektami) i Tnie jest referencją ( constnie dotyczy referencji z tego samego powodu) , to typ funkcji. int(lub jakikolwiek inny typ niefunkcjonalny-nie-referencyjny) nie pasowałby, ponieważ is_const<const int>::valuejest true.

Zgodnie ze standardem C ++ 17 § 11.3.5 Funkcje / sekcja 7 : (moje podkreślenie)

Efekt cv-qualifier-seq w deklaratorze funkcji nie jest taki sam, jak dodanie kwalifikacji cv nad typem funkcji. W tym drugim przypadku kwalifikatory cv są ignorowane. [Uwaga: typ funkcji, który ma sekwens kwalifikujący cv, nie jest typem kwalifikowanym cv; nie ma typów funkcji zakwalifikowanych do CV. - uwaga końcowa] [...]

Ayxan
źródło
5
Ach .... brakowało mi „const” w części is_const. To ma sens.
Rian Quinn
54

Istnieją tylko dwie kategorie typów w języku, które nie mogą mieć stałej kwalifikacji: typy referencyjne i typy funkcji. Jeśli więc const Tnie jest typem stałym, oznacza to, że Tjest albo typem funkcji, albo typem odniesienia. Jeśli możesz wykluczyć typy referencyjne, pozostaną tylko typy funkcji.

Zauważ, że typ funkcji, która przenosi kwalifikator cv, taki jak int(int) const, nie jest typem o stałej kwalifikacji. Jest to przykład „obrzydliwego typu funkcji”, którego jedynym faktycznym zastosowaniem jest komponowanie lub rozkładanie typów funkcji wskaźnik na element członkowski. Tego typu int(int) constnie można uzyskać, dodając stałą kwalifikację na górze int(int). Raczej constdotyczy to parametru obiektu domyślnego.

Brian
źródło