括号创建非演绎上下文吗?



temp. deduction .type#17指定

如果在带有非类型模板形参的函数模板声明中,该非类型模板形参用于函数形参列表中的子表达式中,则该表达式是如上所述的非推导上下文。

表示对于下面的f

声明
template<int> struct S {};
template<int i> void f(S<i + 1>) {}

呼叫f(S<42>{})被拒绝。

但是,如果将f的声明更改为

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

只有Clang拒绝调用,错误和之前一样。

那么,在i周围添加括号是否使其成为非推导上下文,因为i(i)的子表达式?

子表达式是相对于直接子表达式定义的:

表达式E的子表达式是E的直接子表达式或E的直接子表达式的子表达式

和直接子表达式部分定义为:

表达式E的直接子表达式为

  • E的操作数组成表达式([exp .prop]),

有更多的可能性,但它们显然不适用于(N)的情况。所以问题是N是否是括号表达式的操作数。

根据[exp .prim.paren]/1:

带括号的表达式(E)是一个主表达式,其类型、值和值类别与E的类型、值和值类别完全相同。除了另有说明外,带括号的表达式可以用于与E完全相同的上下文中,并且具有相同的含义。

重点补充道。显然,(N)N不是一个操作数,所以它不是一个直接的子表达式,因此N不是子表达式。

由于[temp. deduction .type]/17中没有任何"另有指示"的内容,很明显(N)N可以被相同地使用。

最新更新