Почему две функции не являются неоднозначными?

У меня есть устаревший код, который имеет следующие конструкторы.

CAgs (int ar, bool isReady);
CAgs (int ar, const char* options[][2] = NULL);

Он компилируется, но не будет ли это неоднозначным вызовом? Если я позвоню CAgs (10, 0);какой конструктор будет вызываться?

Зависит ли это поведение от компилятора?

2

Решение

В северном направлении Я интерпретировал ваш вопрос как «почему это компилируется? Разве это не двусмысленно если бы я был называть это так?

Этот звонок является двусмысленный поскольку вызов каждого конструктора потребует неявного преобразования с CAgs (10, 0);

Цитировать некоторые источники:

§ 4.10.1 для const char* options[][2] тип

Константа нулевого указателя является целочисленным литералом (2.14.2) со значением ноль
или значение типа std :: nullptr_t. Константа нулевого указателя может быть
преобразован в тип указателя; результатом является значение нулевого указателя
этот тип и отличается от любого другого значения объекта
указатель или тип указателя функции. Такое преобразование называется нулевым
преобразование указателя

4.12.1 для bool тип

Значение арифметики, перечисление с незаданной областью, указатель или указатель на
тип члена может быть преобразован в значение типа bool. Нулевое значение,
значение нулевого указателя или значение указателя нулевого элемента преобразуется в
ложный; любое другое значение преобразуется в true.

Код наверняка компилируется, потому что параметры — это два разных и допустимых типа, и если вы передадите что-то, что не требует неоднозначного неявного преобразования, оно будет работать правильно. Но это не значит, что это не CAgs (10, 0);

В качестве небольшого несвязанного sidenote значение по умолчанию для указателя заставляет работать только следующее: CAgs (10);, То же самое для любого другого ненулевого типа ( bool конструктор будет выбран).

0

Другие решения

Это должно быть неоднозначным.

НКУ

лязг

VC ++

1

Вызов CAgs (10, 0); неоднозначно, потому что int 0 является кандидатом на bool а также указатель Ненулевой int назвал бы CAgs (int ar, bool isReady); Однако, потому что bool это только кандидат в ненулевом случае.

1

И то и другое int в bool так же как 0 указатель является интегральное преобразование (4.7 [conv.integral]), так что оба преобразования имеют одинаковый порядок, что делает их неоднозначными. Это, однако, применяется только в том случае, если int это так называемый константа нулевого указателя лайк NULL или же 0в противном случае int преобразование указателя не является кандидатом, а int в bool один выбран.

1

Это неоднозначно. Для разрешения требуется явное приведение, например:

CAgs(4, (bool)0);

или же

CAgs(4, (char *)0);
1

Интегральные преобразования

Значение типа integer или перечисления с незаданной областью может быть
преобразован в любой другой целочисленный тип. Если преобразование указано в
неотъемлемые акции, это продвижение, а не конверсия.

  • Если тип назначения не имеет знака, полученное значение является наименьшим значением без знака, равным исходному значению по модулю 2n.
    где n — количество битов, используемых для представления типа назначения.
  • То есть, в зависимости от того, является ли тип назначения шире или уже, целые числа со знаком расширяются знаком [сноска 1] или усекаются, а целые числа без знака расширяются нулями или усекаются соответственно.
  • Если тип назначения подписан, значение не изменяется, если исходное целое число может быть представлено в типе назначения. В противном случае результат определяется реализацией.
  • Если тип источника — bool, значение false преобразуется в ноль, а значение true преобразуется в значение один из
    тип назначения (обратите внимание, что если тип назначения int, это
    это целочисленное продвижение, а не целочисленное преобразование)
  • Если тип назначения — bool, это логическое преобразование (см.
    ниже)

Преобразование указателя

  • Константа нулевого указателя (см. NULL) может быть преобразована в любой тип указателя, и результатом является значение нулевого указателя этого типа. Такое преобразование (известное как преобразование нулевого указателя) позволяет преобразовывать в квалифицированный cv тип как одно преобразование, то есть оно не считается комбинацией числовых и квалифицированных преобразований.
  • Указатель prvalue на любой (необязательно cv-квалифицированный) тип объекта T может быть преобразован в указатель prvalue в (идентично cv-квалифицированному)
    недействительным. Полученный указатель представляет в памяти тот же байт, что и
    исходное значение указателя. Если исходный указатель нулевой
    значение указателя, результатом является нулевое значение указателя
    тип назначения.
  • Указатель prvalue на (необязательно cv-квалифицированный) тип производного класса может быть преобразован в prvalue-указатель на его доступный, однозначный (идентично cv-квалифицированный) базовый класс. Результатом преобразования является указатель на подобъект базового класса в указанном объекте. Значение нулевого указателя преобразуется в значение нулевого указателя
    типа назначения.

Булевы преобразования

Значения целочисленного, с плавающей точкой, перечисление с незаданной областью, указатель,
и типы указателя на член могут быть преобразованы в значения типа bool.

Нулевое значение (для целого, с плавающей запятой и с незаданной областью
перечисление) и нулевой указатель и нулевой указатель на член
значения становятся ложными. Все остальные ценности становятся правдой.

Prvalue типа std :: nullptr_t, включая nullptr, может быть преобразовано в prvalue типа bool в контексте прямой инициализации (начиная с C ++ 14). Полученное значение ложно.

Источник: Неявные преобразования по совместительству

Поскольку оба они являются преобразованиями, они имеют одинаковый порядок, поэтому это должно быть неоднозначным. Но только в случае 0, потому что 0 можно преобразовать в NULL.

1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector