隐藏成员函数模板 - 哪个编译器是正确的?

msc*_*msc 23 c++ gcc templates clang c++11

我编写了以下隐藏成员函数模板的代码.

#include <iostream>

struct A 
{
    template<int> void func()
    {
        std::cout<<"Function tamplate of A"<<std::endl;
    }
};

struct B : A 
{
    template<char> void func()
    {
        std::cout<<"Function tamplate of B"<<std::endl;
    }
    using A::func;
};

int main()
{
    B().func<0>();
}
Run Code Online (Sandbox Code Playgroud)

这个程序在Clang编译器中工作.现场演示Clang

但是,GCC编译器会产生歧义错误.现场演示GCC

source_file.cpp: In function ‘int main()’:
source_file.cpp:22:17: error: call of overloaded ‘func()’ is ambiguous
     B().func<0>();
Run Code Online (Sandbox Code Playgroud)

那么,哪个编译器是正确的?

Sto*_*ica 12

关于OP中的例子:正如WF所指出的那样,重要的是那些是成员函数模板.你添加了一个using声明,它指定了([namespace.udecl]/15):

当using声明将基类中的名称带入派生类范围时,派生类中的成员函数和成员函数模板将覆盖和/或隐藏具有相同名称的成员函数和成员函数模板,parameter-type-list,cv - 基类中的-qualification和ref-qualifier(如果有)(而不是冲突).

请注意不考虑模板参数.Clang通过隐藏int版本来正确处理代码.


另一方面,如果检查你的帖子中建议的例子tobi303,GCC就是正确的.这根本没有指定以某种方式解决.

首先,有[temp.fct.spec]/3:

可以从显式模板参数列表中省略可以从默认模板参数推导或获得的尾随模板参数.[...] 在演绎完成和失​​败的上下文中,或者在未进行演绎的上下文中,如果指定了模板参数列表,并且它与任何默认模板参数一起标识单个函数模板特化,则模板-id是函数模板特化的左值.

以粗体显示的文本表示只有在我们提供的模板参数指定单个特化时,您的程序才是格式良好的.表面上看,它没有,因为根据[temp.arg.nontype]/1:

非类型非模板模板参数的模板参数应为以下之一:

  • 对于整数或枚举类型的非类型模板参数,模板参数类型的转换常量表达式;

并且0适合两个重载作为转换的常量表达式.由于模板参数没有任何ICS排名,这是不明确的.