Частичное упорядочение с L-значением-ref

Почему это неоднозначно?

template<class T> void g(T)  {}   // 1
template<class T> void g(T&) {}   // 2

int main() {
    int  q;
    g(q);
}

Я понимаю, что это частичный порядок контекста. И мое, возможно, ошибочное мышление: любой T& from #2 может быть помещен в #1, но не любой T из # 1 является законным в #2. Так что частичное упорядочение должно работать.

2 ответа

Решение

ХОРОШО. Я думаю, это то, что вы ищете. Не вдаваясь в двойное применение сравнения параметров с типами аргументов, в стандарте выпало следующее:

C++ 11 §14.8.2.4p5

Перед выполнением частичного упорядочения выполняются определенные преобразования для типов, используемых для частичного упорядочения:

  • Если P является ссылочным типом, P заменяется указанным типом.
  • Если A является ссылочным типом, A заменяется указанным типом.

C++ 11 §14.8.2.4p6 продолжает говорить о том, что происходит, когда оба являются ссылочными типами, но это здесь не применимо (хотя и интересное чтение). в твоем случае только один есть, поэтому его раздевают. Оттуда:

C++ 11 §14.8.2.4p7

Удалите все cv-квалификаторы верхнего уровня:

  • Если P является cv-квалифицированным типом, P заменяется cv-неквалифицированной версией P.
  • Если A является cv-квалифицированным типом, A заменяется cv-неквалифицированной версией A.

Теперь оба абсолютно равны, и, таким образом, у вас есть двусмысленность, которая, я считаю, подтверждена в C++11 §14.8.2.4p10. Текст C++11 §14.8.2.4p9 охватывает оба ссылочных типа, что, опять же, здесь не так:

C++ 11 §14.8.2.4p10

Если для каждого рассматриваемого типа данный шаблон, по крайней мере, столь же специализирован для всех типов и более специализирован для некоторого набора типов, а другой шаблон не более специализирован для каких-либо типов или, по крайней мере, не так специализирован для любых типов, то данный Шаблон более специализирован, чем другой шаблон. В противном случае ни один шаблон не является более специализированным, чем другой.

Но чтение стандарта в этом разделе для меня все равно, что расшифровать греческий язык, так что я могу быть далеко от базы. (без обид грекам =P).

Это, однако, заставило меня думать " const T& против Tс учетом того же условия вызова g(q), также должен быть неоднозначным, если все, что я только что прочитал, применяется как написано."Конечно, я попробовал это, и та же самая неоднозначность была отмечена.

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

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

Другие вопросы по тегам