【问题标题】:Why using declaration is needed when an overload is deleted为什么删除重载时需要使用声明
【发布时间】:2023-03-25 21:07:01
【问题描述】:

为什么我必须重新引入删除了一些重载的函数的名称?

#include <string>

struct A
{
    void f(int) {}
    void f(double) {}
    void f(const std::string&) {}
};

struct B : public A
{
    using A::f; // needed to compile : why ?
    void f(int)=delete;
    void f(double)=delete;
};

int main()
{
    B b;
    b.f(std::string("toto"));
}

【问题讨论】:

    标签: c++ class scope function-declaration using-declaration


    【解决方案1】:

    结构B中的这些记录

    void f(int)=delete;
    void f(double)=delete;
    

    是在基础结构 A 中隐藏同名 f 的声明的声明。

    所以 B 中的 using 声明

    using A::f; // needed to compile : why ?
    

    使在 A 中声明的名称为 f 的所有函数在结构 B 中可见。

    考虑以下演示程序,其中一种情况下没有 using 声明,而在第二种情况下有 using 声明。

    #include <iostream>
    
    int main() 
    {
    {   
        struct A
        {
            void f( char ) const
            {
            std::cout << "A::f( char ) const\n";
            }
        };
    
        struct B : A
        {
            void f( int ) const
            {
                std::cout << "B::f( int ) const\n";
            }
        };
    
    
        B b;
        
        b.f( 'A' );
    }
    
    std::cout << '\n';
    
    {   
        struct A
        {
            void f( char ) const
            {
            std::cout << "A::f( char ) const\n";
            }
        };
    
        struct B : A
        {
            using A::f;
            void f( int ) const
            {
                std::cout << "B::f( int ) const\n";
            }
        };
    
    
        B b;
        
        b.f( 'A' );
    }
    
        return 0;
    }
    

    程序输出是

    B::f( int ) const
    
    A::f( char ) const
    

    【讨论】:

      【解决方案2】:

      这是合法的,但至少是一致的。

      我想你在想,当一个函数在派生类中被重写时,基类中的函数,或者至少是它的标识符,在概念上被导入派生类,然后 被覆盖。但实际上,正在发生的事情是调用b.f 的代码甚至从未看到 A::f,因为查找在到达那里之前就成功了。所有这些都发生在重载决议发生之前。

      因此,如果您想访问来自A 的各种重载以及B 的各种重载(包括已删除的重载),则需要将它们导入B,因此编译器之前不会放弃看到他们。

      【讨论】:

        【解决方案3】:

        B 类中的单个 f 声明隐藏了基类 Af所有声明。

        甚至将函数标记为已删除也被视为声明。

        【讨论】:

          猜你喜欢
          • 2021-03-09
          • 1970-01-01
          • 2011-06-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-08-17
          相关资源
          最近更新 更多