частичный заказ с L-значением-ref


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

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. Так что частичный заказ должен работать.

2 6

2 ответа:

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

C++11 §14.8.2. 4p5

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

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

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

C++11 §14.8.2. 4p7

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

  • Если P является CV-квалифицированным типом, то P заменяется cv-неквалифицированным вариантом P.
  • , Если A является резюме-квалифицированный тип, а заменяется резюме-неквалифицированный версия А.
Теперь оба полностью равны, и таким образом у вас есть ваша двусмысленность, которая, как я полагаю, затвердевает из C++11 §14.8.2.4p10. Текст C++11 §14.8.2. 4p9 охватывает оба типа ссылок, что, опять же, здесь не так:

C++11 §14.8.2. 4p10

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

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

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

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

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