My reading of the standard is that it should be allowed, but I suppose the implementors of GCC and Clang disagree with my interpretation, and they're probably correct. For a definitive answer, it might be a good idea to ask the std-discussion@isocpp.org mailing list (I'll shoot them an email). The wording might be a defect.
According to [temp.arg.nontype], one of the possible forms for a non-type template argument is:
... a constant expression (5.19) 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 &
id-expression, where the id-expression is the name of an object or function, except that the
&
may be omitted if the name refers to a function or array and shall be omitted if the corresponding
template-parameter is a reference ...
It all hinges on what "ignoring parentheses" means. GCC and Clang both accept (&x)
but not &(x)
; they seem to have decided that "ignoring parentheses" means only on the outside, not around the id-expression. If this was the intent of the standards committee, the language should be clarified.
Edit: In the C++17 draft, this is unambiguously allowed, since the form of allowable non-type template arguments has been relaxed considerably:
A template-argument for a non-type template-parameter shall be a converted constant expression ([expr.const]) of the type of the template-parameter. 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):
- a subobject ([intro.object]),
- a temporary object ([class.temporary]),
- a string literal ([lex.string]),
- the result of a
typeid
expression ([expr.typeid]), or
- a predefined
__func__
variable ([dcl.fct.def.general]).