c++ - 基类和派生类中的模板成员之间的重载解析

标签 c++ c++14 sfinae overload-resolution using-declaration

Microsoft 编译器 (Visual Studio 2017 15.2) 拒绝以下代码:

#include <type_traits>

struct B
{ 
    template<int n, std::enable_if_t<n == 0, int> = 0>
    void f() { }
};

struct D : B
{
    using B::f; 
    template<int n, std::enable_if_t<n == 1, int> = 0>
    void f() { }
};

int main()
{
    D d;
    d.f<0>();
    d.f<1>();
}

错误是:

error C2672: 'D::f': no matching overloaded function found
error C2783: 'void D::f(void)': could not deduce template argument for '__formal'
note: see declaration of 'D::f'

Clang 也拒绝了它:

error: no matching member function for call to 'f'
    d.f<0>();
    ~~^~~~
 note: candidate template ignored: disabled by 'enable_if' [with n = 0]
    using enable_if_t = typename enable_if<_Cond, _Tp>::type;

GCC 完全接受它。哪个编译器是正确的?

添加:

以 SFINAE 的形式

template<int n, typename = std::enable_if_t<n == 0>>
...
template<int n, typename = std::enable_if_t<n == 1>>

GCC 也会产生一个错误:

error: no matching function for call to ‘D::f<0>()’
 d.f<0>();
        ^
note: candidate: template<int n, class> void D::f()
 void f()
      ^
note:   template argument deduction/substitution failed:

最佳答案

将 cppleaner 的评论转化为答案:

来自 namespace.udecl#15.sentence-1 :

When a using-declarator brings declarations from a base class into a derived class, member functions and member function templates in the derived class override and/or hide member functions and member function templates with the same name, parameter-type-list, cv-qualification, and ref-qualifier (if any) in a base class (rather than conflicting)

不幸的是,模板参数不计算在内,f 的参数类型列表为空,不是 const 也没有引用限定符。

Derived::f 因此隐藏了 Base::f

gcc 接受该代码是错误的。

所以修复它的方法是默认参数(返回类型也不算):

struct B
{ 
    template <int n>
    void f(std::enable_if_t<n == 0>* = nullptr) { }
};

struct D : B
{
    using B::f; 
    template <int n>
    void f(std::enable_if_t<n == 1>* = nullptr) { }
};

关于c++ - 基类和派生类中的模板成员之间的重载解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45576462/

相关文章:

c++ - 使用信号情报

c++ - 常量和重载构造函数

c++ - 来自单个整数参数的可变参数模板声明?

c++ - 使用 `std::enable_if` 转发包装器失败

c++ - 创建带参数的 C++ 构造函数

c++ - 使用 Procmon 分析读操作

c++ - 无法使方法存在检测机制起作用

c++ - 将 0,1,2,...,N-1 作为参数传递给函数

c++ - SFINAE C++ 方法检查

C++ 分割字符串的函数