Как реализована функция std :: is_function?

82

Как следующая реализация для 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функция an будет под этим определением. Что мне не хватает?

Риан Куинн
источник
10
Подумай о !is_constчасти.
aschepler
Почему типы функций не могут быть постоянными? Это связано с отвратительными типами?
jtbandes
4
@jtbandes потому что функции - это одна из немногих вещей в C ++, которые не являются объектами.
Айксан
1
Я думаю, потому что в некотором смысле это всегда
константа
Я чувствую, что название вводит в заблуждение. "Как это действительная реализация std :: is_function?" кажется более подходящим.
говорит Вэл Восстановить Монику

Ответы:

73

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

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

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

Ayxan
источник
5
Ах .... Я пропустил "const" внутри части is_const этого. В этом есть смысл.
Риан Куинн
54

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

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

Брайан
источник