In C++17, from [temp.arg.nontype]:
For a non-type template-parameter of reference or pointer type, the value of the constant expression shall not refer to (or for a pointer type, shall not be the address of):
Where a subobject is, from [intro.object]:
Objects can contain other objects, called subobjects. A subobject can be a member subobject ([class.mem]), a base class subobject ([class.derived]), or an array element.
&m as a non-type template argument is fine - it points to an object. That object happens to be initialized from
n, but that doesn't matter.
On the other hand,
&n both point to an element of the array
n, which is to say they both point to a subobject of
n, and hence this is not allowed.
&m are not related.
In C++11 and C++14, the wording was inclusive rather than exclusive, but the conclusion is the same:
A template-argument for a non-type, non-template template-parameter shall be one of:
- a constant expression ([expr.const]) that designates the address of a complete object with static storage duration and external or internal linkage or a function with external or internal linkage, including function templates and function template-ids but excluding non-static class members, expressed (ignoring parentheses) as [...]
A pointer to
m is allowed, a pointer to
n is not.