Разрешение перегрузки C ++ - неоднозначное совпадение - PullRequest
1 голос
/ 29 апреля 2020

Я пытался экспериментировать с некоторыми базовыми c концепциями разрешения перегрузки, используя следующий тестовый код:

void foo()
{
   void F(int x, int y);        // F1
   void F(char x, double y);    // F2
   F('A', 5);
}

Я "пытался" понять применимые части стандарта C ++ 17 и я также посмотрел на cppreference.com. Насколько я понимаю, последовательность преобразования для F1 состоит из повышения и точного соответствия, тогда как последовательность преобразования для F2 состоит из точного соответствия и преобразования. cppreference.com частично заявляет, что

...
F1 is determined to be a better function than F2 if implicit conversions for all 
arguments of F1 are not worse than the implicit conversions for all arguments of 
F2, and
1) there is at least one argument of F1 whose implicit conversion is better than 
the corresponding implicit conversion for that argument of F2
...

Исходя из всего вышесказанного, я решил, что F1 следует принять в качестве лучшего кандидата, поскольку худшее преобразование для F1 лучше, чем худшее преобразование для F2. Однако и компиляторы Microsoft, и minGW генерируют «неоднозначную» ошибку сопоставления. Очевидно, я что-то упустил. Я был бы признателен за объяснение того, что мне не хватает, и ссылку на эту информацию в C ++ 17. Спасибо!

1 Ответ

1 голос
/ 29 апреля 2020

При определении, какую функцию вызывать, сначала вычисляются все жизнеспособные кандидаты. Каждая из этих функций затем упорядочивается в соответствии с количеством необходимых неявных преобразований. Поэтому, учитывая вызов:

F('a', 5);

, какие неявные преобразования необходимо выполнить?

F1 // 1st argument: char -> int
   // 2nd argument: int -> int (none)

F2 // 1st argument: int -> int (none)
   // 2nd argument: int -> double 

, поскольку и F1, и F2 должны выполнять ровно одно неявное Конверсия каждого, они оба считаются одинаково хорошими, и вызов неоднозначен. В частности, оба этих преобразования имеют одинаковый ранг, то есть они выполняют интегральное продвижение и продвижение с плавающей запятой соответственно.

Очевидно, что существует больше правил, которые охватывают больше случаев, но в этом случае между этими двумя функциями не существует t-1012-прерывателя.

...