为什么删除重载时需要使用声明
Why using declaration is needed when an overload is deleted
为什么我必须重新引入删除了一些重载的函数的名称?
#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"));
}
B
class 中 f
的单个声明隐藏了 所有 f
的声明 A
class.
甚至将函数标记为已删除也被视为声明。
结构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
虽然墨守成规,但至少是一贯的。
我想你在想,当一个函数在派生 class 中被覆盖时,其机制是来自基础 class 的函数,或者至少它的标识符,在概念上是输入派生 class 和 then 覆盖。但实际上,正在发生的是调用 b.f
的代码甚至从未 看到 A::f
,因为查找在到达那里之前就成功了。在重载决议发生之前发生的所有事情。
因此,如果您想访问 A
中的各种重载以及 B
中的各种重载(包括已删除的重载),则需要将它们导入 B
,因此编译器在看到它们之前不会放弃。
为什么我必须重新引入删除了一些重载的函数的名称?
#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"));
}
B
class 中 f
的单个声明隐藏了 所有 f
的声明 A
class.
甚至将函数标记为已删除也被视为声明。
结构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
虽然墨守成规,但至少是一贯的。
我想你在想,当一个函数在派生 class 中被覆盖时,其机制是来自基础 class 的函数,或者至少它的标识符,在概念上是输入派生 class 和 then 覆盖。但实际上,正在发生的是调用 b.f
的代码甚至从未 看到 A::f
,因为查找在到达那里之前就成功了。在重载决议发生之前发生的所有事情。
因此,如果您想访问 A
中的各种重载以及 B
中的各种重载(包括已删除的重载),则需要将它们导入 B
,因此编译器在看到它们之前不会放弃。