Исходный ответ:
, поскольку функция-член не является функцией, а указатель на функцию-член не является указателем на функцию.Поэтому правила распада не применяются.
Кроме того, в C ++ есть тип функции, но нет функции-члена.Таким образом, вы можете использовать функцию в местах, где ожидается указатель на функцию, но вы не можете использовать функцию-член, потому что нет такой вещи, только функция указатель на член.F в вашем примере это функция.С другой стороны, Fred :: f ... ну, ничего.
Кроме того, я бы сказал, что "имя функции может разрушаться ...".Нет, имя ничего не может сделать, l-значение типа функции может быть неявно преобразовано в указатель на функцию, и это является преобразованием идентификатора в том, что касается разрешения перегрузки
Редактирование, чтобы уточнить мой ответ:
Каждое выражение в C ++ имеет тип и значение.Значение одного типа может иногда преобразовываться в значение другого типа.Эти преобразования ранжируются таким образом, чтобы сделать одно преобразование лучше другого, главным образом для разрешения перегрузки функций.
Один из типов преобразований называется преобразованием lvalue-to-rvalue.Когда lvalue появляется в контексте, где требуется rvalue, происходит это преобразование.Обычно этот тип преобразования ничего не делает, например:
int i = 4, j = 5;
i = j;
во второй строке j является lvalue, но здесь необходимо r-значение, поэтому j преобразуется в r-значение.Но это не наблюдаемое преобразование, не так ли?Но есть случаи, когда можно наблюдать преобразование lvalue в rvalue.То есть значение массива n T может быть преобразовано в значение типа T*
, значение которого является адресом первого элемента массива и значение типа «функция с сигнатурой S» значение типа «указатель на функцию с сигнатурой S», значением которого является адрес функции
Это означает, что когда мы назначаем функциюв указатель на функцию lvalue неявно преобразуется в ее адрес.
void f() {}
void (*p) () = f; //f is converted to rvalue
f является выражением и имеет тип.Тип f: void()
В C ++ нет такого типа, как member-function
Существуют функции указателей на члены, но не функции-членысамих себя.Я говорю конечно о нестатических функциях.Статические функции работают так же, как и обычные функции, то есть вам не нужно писать &X::f
, вместо этого вы можете написать X::f
Почему?Потому что X :: f имеет функцию типа и происходит указанное преобразование.Однако если f нестатическое, то X :: f имеет тип ... что?Ах да, у него нет типа, и, следовательно, он не является выражением, и поэтому не имеет значения, и поэтому это значение не может быть преобразовано во что-либо.
Цитата из стандарта: 5.3.1, пункт 3 Aуказатель на член формируется только тогда, когда используется явное &, а его операндом является квалифицированный идентификатор, не заключенный в скобки.[Примечание: то есть выражение & (квалифицированный идентификатор), где квалифицированный идентификатор заключен в круглые скобки, не образует выражение типа «указатель на член». Также не используется квалифицированный идентификатор, поскольку не существует неявного преобразованияот квалифицированного идентификатора для нестатической функции-члена к типу «указатель на функцию-член», поскольку существует от lvalue типа функции до типа «указатель на функцию» (4.3).И & unqualified-id также не является указателем на член, даже в пределах класса unqualified-id.]
Надеюсь, это было яснее ...