Ответ 1
Это точно описано CWG 2091:
В соответствии с пунктом 14.8.2.5 [temp.deduct.type] 17,
Если
P
имеет форму, содержащую<i>
, и если тип соответствующего значенияA
отличается от типаi
, то вывод выходит из строя.Это дает неверный результат для примера, например:
template<int &> struct X; template<int &N> void f(X<N>&); int n; void g(X<n> &x) { f(x); }
Здесь
P
естьX<N>
, который содержит<i>
. Типi
равенint&
. Соответствующее значение изA
равноn
, которое является значением gl типаint
. Предположительно это должно быть действительно.Я думаю, что это правило означает сказать что-то вроде
Если
P
имеет форму, содержащую<i>
, а типi
отличается от типа соответствующего шаблонного параметра шаблона названный вложенным идентификатором simple-template-id, вывод не выполняется.
Как отмечено @dyp, [temp.deduct.type]/17 должно быть более разрешительным. В вашем примере аргумент в FooClass<F>
(F
) не имеет ссылочного типа - это значение l типа типа foo
. Параметр шаблона FooClass
является ссылкой. DR был разрешен в прошлом году.