使用“template”关键字作为对转换函数模板的显式访问前缀是否合法? [复制]

2024-01-09

考虑以下程序:

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 拒绝,并显示以下错误消息:

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

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

事实上,(B) 应该是合法的,根据[临时名称]/5 https://timsong-cpp.github.io/cppwp/n4659/temp.names#5:

以关键字为前缀的名称template 应是一个模板 ID或者名称应引用类模板或别名模板。 [Note:关键词template可能不适用于类模板的非模板成员。 —end note ] [ Note:正如情况一样typename前缀,即template prefix 在非绝对必要的情况下允许;即,当嵌套名称说明符或左边的表达式-> or .不依赖于模板参数,或者使用不出现在模板的范围内。 —end note ]

并作为管辖的禁令[临时名称]/4 https://timsong-cpp.github.io/cppwp/n4659/temp.names#4不适用:

关键词template据说出现在顶层合格的 ID如果它出现在 a 之外模板参数列表 or decl类型说明符。 [...]可选关键字 template出现在顶层被忽略. [...]

并且最多仅声明应忽略该关键字(但不声明该程序格式错误)。

我没有找到任何条款[类.转换.fct] https://timsong-cpp.github.io/cppwp/n4659/class.conv.fct or [温度扣除转换] https://timsong-cpp.github.io/cppwp/n4659/temp.deduct.conv这与这个论点相冲突。

Question

  • 对转换函数模板的显式访问添加前缀是否合法template关键词?

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

This is CWG 缺陷报告 96 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#96截至 GCC 10,该问题尚未得到解决。相关 bug GCC 票证55588 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55588提到它正在为 GCC 11 实施。


正如答案中所涵盖的是否可以使用显式模板参数调用模板化的用户定义转换运算符? https://stackoverflow.com/questions/55275983/is-it-possible-to-call-templated-user-defined-conversion-operator-with-explicit,转换函数模板名称不命名模板 ID;引用语法来自模板 ID from [临时名称]/1 https://timsong-cpp.github.io/cppwp/n4659/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关键字不能用作转换函数模板名称的前缀,因为后者不是模板 ID.

有趣的是,Clang 在引用某个对象时并不拒绝使用关键字。操作员功能 ID (which is a 模板 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。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用“template”关键字作为对转换函数模板的显式访问前缀是否合法? [复制] 的相关文章

  • Qt 图表和数据可视化小部件

    我已经安装了 Qt 5 7 来尝试 Qt 图表和 Qt 数据可视化 但我在 Qt Designer 和 Qt Creator 中都找不到新的小部件 有什么建议我应该做什么才能让新的小部件出现在设计器中 我今天遇到了完全相同的问题 默认情况下
  • 生成多个随机数

    我想生成 25 个唯一的随机数并将它们列在控制台中 数字的长度应至少为 10 个字符 有什么简单的方法可以做到这一点吗 尝试将数字构建为字符串 并使用 HashSet 确保它们是唯一的 Random random new Random Ha
  • STL之类的容器typedef快捷方式?

    STL 容器的常见模式是这样的 map
  • 平滑手绘曲线

    我有一个允许用户绘制曲线的程序 但这些曲线看起来不太好 它们看起来摇摇欲坠 而且是手绘的 所以我想要一种能够自动平滑它们的算法 我知道平滑过程中存在固有的模糊性 因此它不会每次都完美 但这种算法似乎确实存在于多个绘图包中 并且它们工作得很好
  • 最新 .Net MongoDb.Driver 的连接问题

    我创建了一个 MongoLab 沙箱数据库 我与 MongoChef 连接 效果很好 我通过 Nuget 安装了 MongoDB Driver 2 2 2 我编写了一些简单的 C 演示代码 但就是无法使其工作 连接字符串是直接从 Mongo
  • C# 无法捕获 SerializationException

    我的程序在加载序列化文件的部分遇到问题 如果文件无法反序列化 我希望很好地失败 但由于某种原因 我的程序将中断而不是进入 catch 子句 这是我的代码 using FileStream fs new FileStream openFile
  • 嵌入资源文件的路径

    我的资源文件中有一个图标 我想引用它 这是需要图标文件路径的代码 IWshRuntimeLibrary IWshShortcut MyShortcut MyShortcut IWshRuntimeLibrary IWshShortcut W
  • 如何在C中同时运行两个子进程?

    所以我开始学习并发编程 但由于某种原因我什至无法掌握基础知识 我有一个名为 fork c 的文件 其中包含一个 main 方法 在此方法中 我将 main 分叉两次 分别进入子进程 1 和 2 在孩子 1 中 我打印了字符 A 50 次 在
  • 无法加载程序集问题

    我收到以下错误 无法加载程序集 错误详细信息 System BadImageFormatException 无法加载文件或程序集 文件 或其依赖项之一 该程序集是由比当前加载的运行时更新的运行时构建的 无法加载 该程序集是使用 Net Fr
  • 如何减少 MinGW g++ 编译器生成的可执行文件的大小?

    我有一个简单的 Hello world C 程序 在 Win XP 下由 MinGW g 编译器编译为 500kB 可执行文件 有人说这是由于iostream的库和静态链接libstdc dll Using s链接器选项有点帮助 减少了 5
  • 使用数据绑定,如何将包含表情符号的文本绑定到标签并使其正确显示?

    我正在编写一个应用程序来连接 WordPress BuddyPress API 该应用程序将允许用户通过 API 相互发送消息 当这些消息包含表情符号时 我很难正确显示它们 以下是 API 返回的消息文本的简短示例 Hi x1f642 ho
  • 从 DataRow 单元格解析 int [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 如何从 DataRow 单元格解析 int 值 Int32 Parse item QuestionId ToString 这段代码可以工作 但看
  • “1个未解决的外部”C++

    我已经检查了所有文件之间的连接以及类和函数定义 但每次我尝试运行我的程序时 它都会阻止我并告诉我它有 1 个未解析的外部 该程序应该打开多个文件 一个 学生 文件和一个 成绩 文件 从中读取数据 然后使用 查询文件 来查找数据 找到查询中要
  • 卸载程序

    我正在尝试使用此代码卸载程序 但它似乎不起作用 我尝试过其他答案 但似乎也不起作用 有人可以帮助我吗 我正在尝试按给定名称 displayName 卸载该程序 例如 我给出 displayName Appname 那么此代码应该从我的计算机
  • 当我的进程被终止时到底会发生什么?

    我有一个包含本机代码和托管代码的混合进程 在 Windows Server 2003 上运行 当我从进程资源管理器中终止进程时 它会进入 100 cpu 的状态 并在消失之前保持这种状态一段时间 有时甚至 10 分钟 在此期间我无法 杀死
  • 具有四个 && 的 LINQ Where 子句

    我正在尝试在Where 子句中创建一个带有4 个参数的LINQ 查询 这是一个 Windows 8 应用程序项目 我正在使用 SQLite 数据库 SQLite 实现 https github com praeclarum sqlite n
  • 为什么在构造函数中设置字段是(或不是)线程安全的?

    假设您有一个像这样的简单类 class MyClass private readonly int a private int b public MyClass int a int b this a a this b b public int
  • 从脚本启用/禁用 GameObject 组件 [Unity3D]

    我需要获取一个脚本中设置的布尔值 放入名为 bouclier 的变量 以启用或禁用游戏对象 该变量位于游戏对象 Player 中 此处右下角 我需要启用或禁用这个游戏对象 Bouclier01 为此 我将脚本附加到游戏对象 Bouclier
  • 如何在c#中创建多线程

    我需要监听机器中的所有串行端口 假设我的机器有 4 个串行端口 我必须创建 4 个线程并开始分别使用附加线程监听每个端口 我使用此代码来获取我的机器中的端口数量 private SerialPort comPort new SerialPo
  • 如何在 C 中创建最低有效位设置为 1 的掩码

    这个功能如何运作 最低有效 n 位设置为 1 的掩码 Example n 6 gt 0x2F n 17 gt 0x1FFFF 我根本不明白这些 尤其是 n 6 gt 0x2F 另外 什么是面膜 通常的方法是采取1 并将其左移n位 这会给你类

随机推荐