c++ - 函数重载:内置与用户定义类型
问题描述
template <class T>
void foo(T t) {
t.moo();
}
template <class T>
void f(T t) {
foo(t);
}
struct C {
};
void foo(C) {}
void foo(int) {}
int main() {
C c;
f(c);
return 0;
}
上面的代码编译没有错误。如果行“C c;” 替换为“int c;”,编译器将生成错误“no function 'moo' for type 'int'”或类似的东西(MSVC 将编译,但这是另一回事)。如果我们将 int 重载替换为模板特化,一切都会再次起作用。如果将函数“void foo(int)”移到模板代码上方,那也可以。这是怎么回事?
解决方案
这是怎么回事?
依赖于参数的查找 (ADL)。当通过具有至少一个类类型参数的非限定名称调用函数时,除了对函数名称进行正常名称查找外,还会执行 ADL。ADL 在与类关联的命名空间(基本上是定义类的命名空间)中查找函数名称。
重要的属性是,对于函数模板,非限定名称查找仅考虑在模板定义中可见的名称,但 ADL 还考虑在模板实例化时可见的名称。由于非模板重载是在模板之后声明的,因此无法通过普通的非限定名称查找找到它们。但是,foo(C)
可以(并且是)被 ADL 找到,因为C
它是一个类类型。int
不是,所以没有执行 ADL 也foo(int)
没有找到。
推荐阅读
- windows - 如果语句未按预期执行 - 批处理文件
- python - 如何在 tkinter ttk.button 中使用不同颜色为按钮着色?
- python - 添加到不带引号的python列表
- css - 如何用css反转wave svg?
- r - 将日期字符串转换为 R 中的天数
- android - 通过对话框将数据从适配器传递到活动
- c++ - 从 Select 调用返回后,在服务器上处理/重组 TCP 分段数据包的方法
- android-camerax - java.lang.IllegalArgumentException:建议的分辨率地图缺少相机 1 的分辨率
- r - R:将函数逐行应用于表,将查找表中的值作为参数传递
- java - 我的朋友指出[在 main 上抛出是不合适的]。我应该如何以及在哪里修复它?