Как реализована функция std :: is_function? - PullRequest
82 голосов
/ 09 января 2020

Как следующая реализация для std::is_function?

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

(из CPP Ссылка )

Мне кажется, int будет функция в соответствии с этим определением. Чего мне не хватает?

Ответы [ 2 ]

73 голосов
/ 09 января 2020

Давайте go по условиям, как они появляются:
Если const T не является константой (const на самом деле не относится к типам функций, поскольку функции не являются объектами), а T isn это не ссылка (const не относится к ссылкам по той же причине), это тип функции. int (или любой другой тип без функции-ссылки) не подходит, потому что is_const<const int>::value равен true.

В соответствии с C ++ 17 Standard §11.3.5 Функции / раздел 7 : (выделено мной)

Эффект cv-qualifier-seq в объявлении функции это не то же самое, что добавить cv-квалификацию поверх типа функции. В последнем случае cv-квалификаторы игнорируются. [Примечание: Тип функции, имеющий cv-qualifier-seq, не является cv-квалифицированным типом; не существует cv-квалифицированных типов функций. - конец примечания] [...]

54 голосов
/ 09 января 2020

В языке есть только две категории типов, которые не может иметь const-квалификацию: ссылочные типы и типы функций. Таким образом, если const T не может быть типом с константой, это означает, что T является либо типом функции, либо ссылочным типом. Если вы можете исключить ссылочные типы, то у вас останутся только типы функций.

Обратите внимание, что тип функции, который содержит квалификатор cv, такой как int(int) const, равен , а не a конст-квалифицированный тип. Это пример «отвратительного типа функции», единственное реальное использование которого состоит в том, чтобы составлять или разлагать типы указателей на члены-функции. Тип int(int) const нельзя получить, добавив const-квалификацию поверх int(int). Скорее, const применяется к подразумеваемому параметру объекта.

...