【问题标题】:the overload resolution of using base member function introduced into derived class使用派生类中引入的基成员函数的重载决议
【发布时间】:2020-07-19 11:18:15
【问题描述】:

根据标准中的一些引号:
[over.match.funcs]/4

[...] 对于通过 using 声明引入派生类的非转换函数,为了定义隐式对象参数的类型,该函数被认为是派生类的成员。

并考虑以下代码:

#include <iostream>
struct Base {
    void show(double) {
        std::cout << "0" << std::endl;
    }
};
struct Test :Base {
    using Base::show;  //#1
    void show(double) { //#2
        std::cout << "1" << std::endl;
    }
};
int main() {
    Test t;
    t.show(1.2);
}

根据我引用的标准,这意味着将Test类型的隐含对象参数作为#1的类型。
对于#1,声明为show(Test&amp;,double)
对于#2,声明为show(Test&amp;,double)
所以为了重载解析,#1的每个隐式转换序列与#2的隐式转换序列没有区别,t.show(1.2)的调用会模棱两可,但是#2被调用了,为什么?如果我错过了标准中的某些内容,请纠正我。

【问题讨论】:

    标签: c++ language-lawyer using-declaration


    【解决方案1】:

    Test::show(double)Base::show(double) 具有相同的签名;它只是隐藏基类中的那个。

    对于using declaration

    (强调我的)

    如果派生类已经有一个具有相同名称、参数列表和限定条件的成员,则派生类成员隐藏或覆盖(不冲突)从基类。

    来自标准,[namespace.udecl]/14

    当 using-declarator 将基类中的声明带入 派生类、成员函数和成员函数模板 派生类覆盖和/或隐藏成员函数和成员 同名函数模板,参数类型列表 ([dcl.fct])、尾随 requires-clause(如果有)、cv-qualification 和 基类中的引用限定符(如果有的话)(而不是冲突的)。 这种隐藏或覆盖的声明被排除在集合之外 using-declarator 引入的声明。 [ 例子:

    struct B {
      virtual void f(int);
      virtual void f(char);
      void g(int);
      void h(int);
    };
    
    struct D : B {
      using B::f;
      void f(int);      // OK: D​::​f(int) overrides B​::​f(int);
    
      using B::g;
      void g(char);     // OK
    
      using B::h;
      void h(int);      // OK: D​::​h(int) hides B​::​h(int)
    };
    
    ...
    

    【讨论】:

      猜你喜欢
      • 2011-03-26
      • 1970-01-01
      • 1970-01-01
      • 2016-05-21
      • 2021-03-25
      • 1970-01-01
      • 1970-01-01
      • 2019-10-11
      • 1970-01-01
      相关资源
      最近更新 更多