功能模板超载分辨率在Visual C 2017中失败

Function template overload resolution fails in Visual C++ 2017

本文关键字:2017 失败 Visual 超载 分辨率 功能      更新时间:2023-10-16

我试图弄清楚我写的是法律c 14 W.R.T.明确的功能模板超载分辨率。

我认为,以下程序应编译并返回3

各种版本的clang和GCC仅在编译时(使用-std=c++14 -O2)计算该版本,但是Visual C 2017(版本15.5.2;写作时的最新更新)用以下错误消息窒息。

enum class Enum0 { State };
enum class Enum1 { State };
template <Enum0 Param0 = Enum0::State>
int get()
{
    return 1;
}
template <Enum1 Param1>
int get()
{
    return 2;
}
int main()
{
  int sum = 0;
  sum += get(); // should call instantiation of first function template
  sum += get<Enum1::State>(); // should call instantiation of second function template
  return sum;
}

这是Visual C 编译器发出的错误消息:

20 : <source>(20): error C2668: 'get': ambiguous call to overloaded function
11 : <source>(11): note: could be 'int get<Enum1::State>(void)'
5 : <source>(5): note: or       'int get<Enum0::State>(void)'
20 : <source>(20): note: while trying to match the argument list '()'

有关现场演示,请参见https://godbolt.org/g/phh2vy(以及https://godbolt.org/g/bvev79,请参见上一个代码示例,然后再编辑问题)。将编译器更改为MVSC,以查看编译失败。海湾合作委员会和Clang没有任何问题。两者都很好地排放以下X86组件:

        mov     eax, 3
        ret

GCC和Clang太宽了,还是Visual C ?

的问题

这是一个很好的问题,不是。如果我更改第二个通话:

sum += get<Enum1::State, int>(0.0); // should call instantiation of second function template

...然后编译...

注意,我添加了第二个模板参数。在日常工作中,我使用了与MFC兼容的C 的旧方言...因此,用一粒盐来采取推理。但是,由于您仅向模板提供一个参数,而第二个模板需要两个参数,即VC 编译器正在尝试使用第一个模板,因为它具有默认参数,并且只能采用一个参数。因此,它选择了该模板,但不能从ENUM1转换为Enum0。