【问题标题】:Do parentheses create a non-deduced context?括号是否会创建非推断上下文?
【发布时间】:2021-11-23 23:21:02
【问题描述】:

temp.deduct.type#17 指定

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

这意味着f的以下声明

template<int> struct S {};

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

电话f(S&lt;42&gt;{})rejected

但是,如果f的声明改为

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

只有 Clang rejects 调用,和以前一样的错误。

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

【问题讨论】:

    标签: c++ language-lawyer template-argument-deduction


    【解决方案1】:

    子表达式为defined relative to immediate subexpressions:

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

    直接子表达式是defined in part as:

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

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

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

    好吧,不是根据[expr.prim.paren]/1

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

    添加了重点。似乎很明显,在(N) 中,N 不是操作数,因此它不是直接子表达式,因此N 也不是子表达式。

    由于 [temp.deduct.type]/17 中没有任何内容“另有说明”,因此 (N)N 似乎可以相同地使用。

    【讨论】:

    • 是的,这是有道理的。这似乎是一个clang bug。
    • 嗯,看看是否有针对 Clang 的错误报告,我找到了this comment,其中第一句表明括号确实很重要。
    • @cigien:他们可以表示任何他们喜欢的东西,但他们没有指出标准说N(N)的子表达式,我指出了它的所有地方绝对没有说。
    • 是的,这是真的。我会等着看是否有某个地方说()很重要。
    • @cigien:在decltype 中很重要很多
    猜你喜欢
    • 1970-01-01
    • 2012-01-19
    • 2019-05-04
    • 1970-01-01
    • 2012-02-12
    • 2018-07-31
    • 1970-01-01
    • 2021-10-31
    • 1970-01-01
    相关资源
    最近更新 更多