I have the following code, which I cannot get to work:
struct foo {};
foo foo1 = {};
template
class FooClass {};
template
This is precisely covered by CWG 2091:
According to 14.8.2.5 [temp.deduct.type] paragraph 17,
If
P
has a form that contains<i>
, and if the type of the corresponding value ofA
differs from the type ofi
, deduction fails.This gives the wrong result for an example like:
template<int &> struct X; template<int &N> void f(X<N>&); int n; void g(X<n> &x) { f(x); }
Here,
P
isX<N>
, which contains<i>
. The type ofi
isint&
. The corresponding value fromA
isn
, which is a glvalue of typeint
. Presumably this should be valid.I think this rule means to say something like,
If
P
has a form that contains<i>
, and the type ofi
differs from the type of the corresponding template parameter of the template named by the enclosing simple-template-id, deduction fails.
As noted by @dyp, [temp.deduct.type]/17 should be more permissive. In your example, the argument in FooClass<F>
(F
) does not have reference type - it's an lvalue of type foo
. The template parameter of FooClass
is a reference. The DR was resolved last year.