在显式访问转换函数模板前添加关键字'template'是否合法? [英] Is it legal to prefix explicit access to a conversion function template with the 'template' keyword?

查看:64
本文介绍了在显式访问转换函数模板前添加关键字'template'是否合法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下程序:

struct A {
    template <typename T>
    operator T() { return T{}; }
};

int main() {
    (void) A{}.operator int();          // (A)
    (void) A{}.template operator int(); // (B)
}

(A)被GCC和Clang接受,而(B)仅被GCC接受,但被Clang拒绝,并出现以下错误消息:

(A) is accepted by both GCC and Clang, whereas (B) is accepted only by GCC but rejected by Clang with the following error message:

error: expected template name after 'template' keyword in nested name specifier

(void) A{}.template operator int(); // (B)
                    ^~~~~~~~~~~~

Afaict,(B)应该合法,根据 [temp.names]/5 :

Afaict, (B) should be legal, as per [temp.names]/5:

以关键字 template 为前缀的名称应为 template-id ,否则该名称将引用类模板或别名模板..[注意:关键字 template 可能不适用于类模板的非模板成员.— 尾注] [注: typename 前缀, template 前缀一样在并非绝对必要的情况下允许使用;也就是说,当嵌套名称说明符-> 左侧的表达式时.不依赖于模板-参数,否则使用不会出现在模板范围内.— 尾注]

A name prefixed by the keyword template shall be a template-id or the name shall refer to a class template or an alias template. [ Note: The keyword template may not be applied to non-template members of class templates.  — end note ] [ Note: As is the case with the typename prefix, the template prefix is allowed in cases where it is not strictly necessary; i.e., when the nested-name-specifier or the expression on the left of the -> or . is not dependent on a template-parameter, or the use does not appear in the scope of a template.  — end note ]

以及由 [temp.names]/4所禁止的禁令不适用:

如果关键字 template 出现在 template-argument-list 的外部,则它会出现在 qualified-id 的顶级>或 decltype-specifier .[...] 可选关键字 模板出现在顶级.[...]

The keyword template is said to appear at the top level in a qualified-id if it appears outside of a template-argument-list or decltype-specifier. [...] an optional keyword template appearing at the top level is ignored. [...]

,并且最多只能说明应忽略该关键字(但不能指出程序格式不正确).

and, at most, only state that the keyword should be ignored (but not that the program is ill-formed).

我在 [class.conv.fct中找不到任何子句] [temp.deduct.conv] 与此参数相冲突.

I have not found any clause in [class.conv.fct] or [temp.deduct.conv] that conflicts with this argument.

  • 使用 template 关键字为显式访问转换函数模板添加前缀是否合法?
  • Is it legal to prefix explicit access to a conversion function template with the template keyword?

我已经针对各种语言标准版本在各种GCC和Clang版本中测试并重复了上述编译器的行为,但对于本问题,我们可能会重点关注 GCC 10.1.0 >和 Clang 10.0.0 表示 -std = c ++ 17 .

I have tested and repeated the compilers' behaviour above with various GCC and Clang versions for various language standard versions, but for the scope of this question, we may focus on GCC 10.1.0 and Clang 10.0.0 for -std=c++17.

推荐答案

GCC接受该程序是错误的:转换功能模板名称(conversion-function-id)不是模板ID

这是 CWG缺陷报告96 尚未解决.相关的错误GCC凭单 55588 提到它正在为GCC实施11.

GCC is wrong to accept the program: a conversion function template name (conversion-function-id) is not a template-id

This is CWG Defect Report 96, which has, as of GCC 10, has not yet been addressed. The related bug GCC ticket 55588 mentions that it is being implemented for GCC 11.

模板ID 中的语法临时名称]/1 :

As is covered in the answer to Is it possible to call templated user-defined conversion operator with explicit template arguments?, a conversion function template name does not name a template-id; quoting the grammar from template-id from [temp.names]/1:

simple-template-id:
  template-name < template-argument-list_opt>

template-id:
  simple-template-id
  operator-function-id < template-argument-list_opt>
  literal-operator-id < template-argument-list_opt>

template-name:
  identifier

因此,正如在OP中引用的,根据[temp.names]/5, template 关键字不能用作转换函数模板名称的前缀,因为后者是不是 template-id .

Thus, as is quoted in the OP, as per [temp.names]/5, the template keyword may not be used to prefix the name of a conversion function template, as the latter is not a template-id.

可能有意思的是,当引用 operator-function-id ( template-id ):

It may be interesting to point out that Clang does not reject using the keyword when referring to an operator-function-id (which is a template-id):

struct A {
    template <typename T>
    T operator+() { return T{}; }
};

int main() {
    (void) A{}.operator+<int>();          // (A)
    (void) A{}.template operator+<int>(); // (B)
}

如上所述,GCC接受OP的程序是一个错误,因为它违反了[temp.names]/5.

That GCC accepts the OP's program is, as covered above, a bug, as it violates [temp.names]/5.

这篇关于在显式访问转换函数模板前添加关键字'template'是否合法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆