当同时存在模板和非模板重载时,“foo.template bar()”应该做什么?

Hol*_*Cat 30 c++ language-lawyer

一位同事与我分享了这段代码:

run on gcc.godbolt.org

#include <iostream>

struct A
{
    void foo() {std::cout << "1\n";}
    
    template <typename T = int>
    void foo() {std::cout << "2\n";}
};

int main()
{
    A x;
    x.template foo();
}
Run Code Online (Sandbox Code Playgroud)

GCC prints 1、 Clang prints2和 MSVC 抱怨缺少模板参数。

哪个编译器是正确的?

use*_*522 20

[temp.names]/5表示前缀为 的名称template必须是template-id,这意味着它必须具有模板参数列表。(或者它可以引用没有模板参数列表的类/别名模板,但由于@DavisHerring 创作的P1787R6 ,这在当前草案中已被弃用。)

甚至有一个与您的示例几乎相同的示例,表明您的使用格式不template正确。

该要求和示例来自CWG缺陷报告96,其中考虑了没有该要求时可能存在的歧义。

在此打开 GCC 错误报告。我无法找到 Clang 错误报告,但搜索它并不那么容易。然而,其缺陷报告的实施状态页面确实将缺陷报告列为未实施。

  • C++ 已成为一种负担。即使是编译器制造商也无法跟上。 (12认同)

Dav*_*ing 16

MSVC拒绝这一点是正确的:标准仅以此作为示例允许在不带模板参数的类或别名模板的限定名称之前使用解析器指南,但这只是为了与不必要地需要它作为模板模板参数的实现兼容,现在已弃用template