c++ - 未见类外函数重载
问题描述
考虑以下代码片段:
enum class Bar {
A
};
void foo(Bar) {}
struct Baz {
void foo() {
foo(Bar::A);
}
};
它无法编译,来自 gcc 9.2 的消息是:
:12:19: error: no matching function for call to 'Baz::foo(Bar)'
12 | foo(Bar::A);
|
我不怀疑这是一个错误,因为 clang 10 也失败了。关于这种情况,我有两个问题:
标准在哪里为此类重载定义了行为?
以这种方式指定编译器行为的可能原因是什么?
解决方案
foo
对inside的调用Baz::foo()
只会在类中查找名称。如果您的意思是foo
在 class 之外使用声明Baz
,则需要使用范围解析运算符,如下所示:
enum class Bar {
A
};
void foo(Bar) {}
struct Baz {
void foo() {
::foo(Bar::A); // looks up global 'foo'
}
};
请注意,无作用域调用foo
失败,因为Bar::foo
在最近的作用域中找到了一个。如果您对函数命名不同,则在 中找不到函数Bar
,编译器将在函数的外部范围内查找。
enum class Bar {
A
};
void foo(Bar) {}
struct Baz {
void goo() { // not 'foo'
foo(Bar::A); // this is fine, since there is no 'Bar::foo' to find
}
};
这是cppreference对类定义的引用。
e) 如果此类是命名空间的成员,或者嵌套在作为命名空间成员的类中,或者是作为命名空间成员的函数中的本地类,则搜索命名空间的范围直到类、封闭类或函数的定义。如果查找由朋友声明引入的名称:在这种情况下,只考虑最里面的封闭命名空间,否则查找将继续封闭命名空间,直到像往常一样进入全局范围。
当然,这仅适用于类定义,但对于成员函数(这是您的示例),它说
对于在成员函数体内使用的名称、成员函数的默认参数、成员函数的异常规范或默认成员初始值设定项,搜索的范围与 [类定义] 中的相同,...
所以同样的逻辑也适用。
推荐阅读
- python - 何时在 Django 中使用 clear=True 设置相关对象?
- javascript - 将生成的 JSON HTML 表示呈现为 HTML (vue.js — Headless)
- .net - 无法从防火墙后面的服务器访问 Firebase
- java - 为什么我的新计算机 windows 10 上的 JLayeredPane 在我的旧计算机上不起作用?
- python - 如何在熊猫中选择不连续的列
- html - 您可以创建一个 HTML 列表,该列表切入包含渐变的 DIV 吗?
- python - 处理文本文件中的单引号
- c# - 具有线程和等待完成的并行 ForEach
- android - Android:识别用户是否是实时构建的测试人员
- sql - 获取Oracle中具有特定值的列范围