Исходя из вышеизложенного, вполне нормально преобразовать указатель функции или указатель на int
в void*
, а также bool
.
В цитате указано, что указатель на объект может быть преобразован в cv void *
. Функции не являются объектами, и это делает невозможным преобразование в cv void *
, оставляя только bool
.
Однако, учитывая выбор обоих, в какой из них следует преобразовывать указатель?
Он должен преобразоваться в const void *
вместо bool
. Почему? Что ж, приготовьтесь к путешествию, которое начинается в Разрешение перегрузки (§13.3 [over.match] / 2). Акцент мой, конечно.
Но, как только функции-кандидаты и списки аргументов определены, выбор лучшей функции во всех случаях одинаков:
- Сначала выбирается подмножество функций-кандидатов (те, которые имеют надлежащее количество аргументов и удовлетворяют некоторым другим условиям), чтобы сформировать набор жизнеспособных функций (13.3.2).
- Затем выбирается наилучшая жизнеспособная функция, основанная на неявных последовательностях преобразования (13.3.3.1), необходимых для сопоставления каждого аргумента с соответствующим параметром каждой жизнеспособной функции.
Так что насчет этих неявных последовательностей преобразования?
Давайте перейдем к §13.3.3.1 [over.best.ics] / 3 и посмотрим, что такое неявная последовательность преобразования:
Правильно сформированная неявная последовательность преобразования - это одна из следующих форм:
- стандартная последовательность преобразования (13.3.3.1.1),
- определяемая пользователем последовательность преобразования (13.3.3.1.2) или < br> - последовательность преобразования многоточия (13.3.3.1.3).
Нас интересуют стандартные последовательности преобразований. Давайте перейдем к стандартным последовательностям преобразования (§13.3.3.1.1 [over.ics.scs]):
1 Таблица 12 суммирует преобразования, определенные в разделе 4, и разбивает их на четыре непересекающиеся категории: преобразование Lvalue, корректировка квалификации, продвижение и преобразование. [Примечание: эти категории ортогональны по отношению к категории значения, cv-квалификации и представлению данных: преобразования Lvalue не изменяют cv-квалификацию или представление данных типа; Квалификационные корректировки не изменяют категорию значения или представление данных типа; а «Акции» и «Конверсии» не изменяют категорию значения или CV-квалификацию типа. - конец примечания]
2 [Примечание: как описано в разделе 4, стандартная последовательность преобразования представляет собой либо само преобразование идентификатора (то есть без преобразования), либо состоит из одного-трех преобразований из других четырех категорий.
Важная часть находится в / 2. Стандартная последовательность преобразования может быть одним стандартным преобразованием. Эти стандартные преобразования перечислены в Таблице 12, показанной ниже. Обратите внимание, что здесь присутствуют и ваши преобразования указателя, и логические преобразования.
Отсюда мы узнаем кое-что важное: преобразования указателей и логические преобразования имеют одинаковый ранг. Помните об этом, когда мы направляемся к Ранжированию последовательностей неявного преобразования (§13.3.3.2 [over.ics.rank]).
Глядя на / 4, мы видим:
Стандартные последовательности конверсии упорядочены по их рангу: точное совпадение - лучшая конверсия, чем продвижение, а это лучшая конверсия, чем конверсия. Две последовательности преобразования с одинаковым рангом неразличимы, если не применяется одно из следующих правил:
- Преобразование, которое не преобразует указатель, указатель на член или std :: nullptr_t в bool, лучше, чем такое преобразование.
Мы нашли ответ в виде очень четкого утверждения. Ура!
28.08.2014