Do parentheses create a non-deduced context?

Viewed 73

temp.deduct.type#17 specifies that

If, in the declaration of a function template with a non-type template parameter, the non-type template parameter is used in a subexpression in the function parameter list, the expression is a non-deduced context as specified above.

which means for the following declaration of f

template<int> struct S {};

template<int i> void f(S<i + 1>) {}

the call f(S<42>{}) is rejected.

However, if the declaration of f is changed to

template<int i> void f(S<(i)>) {}

only Clang rejects the call, with the same error as before.

So, does adding parentheses around i make it a non-deduced context, because i is a subexpression of (i)?

1 Answers

Subexpressions are defined relative to immediate subexpressions:

A subexpression of an expression E is an immediate subexpression of E or a subexpression of an immediate subexpression of E.

And immediate subexpressions are defined in part as:

The immediate subexpressions of an expression E are

  • the constituent expressions of E's operands ([expr.prop]),

There are more possibilities, but they obviously don't apply to the case of (N). So the question is whether N is an operand of the parenthesis expression.

Well, not according to [expr.prim.paren]/1:

A parenthesized expression (E) is a primary expression whose type, value, and value category are identical to those of E. The parenthesized expression can be used in exactly the same contexts as those where E can be used, and with the same meaning, except as otherwise indicated.

Emphasis added. It seems clear that in (N), N is not an operand, so it is not an immediate subexpression, and therefore N is not a subexpression.

Since there is nothing in [temp.deduct.type]/17 that "indicates otherwise", it seems clear that (N) and N can be used identically.

Related