Почему это неоднозначно?
template<class T> void g(T) {} // 1
template<class T> void g(T&) {} // 2
int main() {
int q;
g(q);
}
Я понимаю, что это частичный порядок контекста. И мое, возможно, ошибочное мышление: любой T& из # 2 может быть помещен в # 1, но не любой T из # 1 является допустимым в # 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)
, также должен быть неоднозначным, если все, что я только что прочитал, применяется как написано. «Конечно, я попробовал, и та же самая неоднозначность была отмечена.
Ваши рассуждения верны, когда эти два типа конкурируют в частичном порядке частичных специализаций шаблона класса, и именно так все и работает.
Но когда ссылочный тип сравнивается с нереференсным типом, общая суть в том, что они неоднозначны в сценарии вызова, если ничто иное не делает один предпочтительным по сравнению с другим. То есть тип ссылки на ссылочный тип не имеет значения в разрешении перегрузки по сравнению с другим, поэтому частичное упорядочение также не учитывает его.