G CC C ++ ошибка? (T) x соответствующий X :: оператор const T & () const отличается от clang's - PullRequest
5 голосов
/ 27 февраля 2020

Я обнаружил несоответствие между G CC и clang (большой диапазон версий, протестированных на godbolt - у всех было одинаковое расхождение) с сопоставлением операторов преобразования. Теперь с использованием более короткого кода воспроизведения Барри - также доступен по адресу godbolt .

struct X {
    template <typename T>
    operator T const&() const;
};

int i = X();

Если operator T const&() const должно совпадать при преобразовании в int (кланг говорит, что да / G CC нужно operator T() const чтобы избежать:

<source>:6:9: error: cannot convert 'X' to 'int' in initialization
        6 | int i = X();
          |         ^~~

Соответствующая часть стандарта C ++ 17 - 15.3 Преобразования [class.conv] . В этом разделе 15.3.5 говорится ...

Функция разрешения перегрузки (16.3.3) выбирает наилучшую функцию преобразования для выполнения преобразования.

..., что почти важно. 16.3.3 - раздел для Лучшая жизнеспособная функция [over.match.best] , но обычно работает в комбинации 16.3.2 жизнеспособных функций [over.match.viable] . В стандарте не представляется явным, что 16,3 .2 применяется здесь, но при условии, что в 16.3.2.1:

из набора функций-кандидатов, сконструированных для данного контекста (16.3.1), выбирается набор жизнеспособных функций

Что поднимает вопрос о том, считает ли G CC operator const T&() const кандидат, который не является жизнеспособным, или даже не кандидат. Однако требования к кандидату на действительность очень просты: правильное количество аргументов и "для каждого аргумента должна существовать неявная последовательность преобразования (16.3.3.1), которая преобразует этот аргумент в соответствующий параметр ... «, что, очевидно, здесь верно, поэтому я считаю, что G CC не должен рассматривать operator const T&() const кандидата, что приводит нас к 16.3.1 функциям-кандидатам и спискам аргументов [over.match.funcs] и, в частности, 16.3.1 / 7:

В каждом случае, когда кандидат является шаблоном функции, кандидаты-специализации шаблона функции генерируются с использованием вывода аргумента шаблона (17.8.3, 17.8.2) , Затем эти кандидаты обрабатываются как функции-кандидаты обычным способом.

Учитывая, что template <typename T> void f(const T&); можно вызывать с типом аргумента int, я думаю, G CC должен был рассмотреть Оператор преобразования является действительным кандидатом, как и Clang.

Я был бы признателен за подтверждение / мысли, хотя. Если люди согласны, я сообщу об ошибке против G CC.

1 Ответ

0 голосов
/ 28 февраля 2020

Это ошибка G CC, как указано T. C. .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...