c++ - 函数重载: builtin vs user defined types

标签 c++ templates overloading

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)”移到模板代码上方,也可以。这是怎么回事?

最佳答案

What's going on?

Argument-dependent lookup (ADL) 。当通过至少一个类类型参数的非限定名称调用函数时,除了函数名称的正常名称查找之外,还会执行 ADL。 ADL 在与类关联的命名空间(基本上是定义类的命名空间)内查找函数名称。

重要的属性是,对于函数模板,非限定名称查找仅考虑在模板定义中可见的名称,但 ADL 也考虑在模板实例化时可见的名称。由于非模板重载是在模板之后声明的,因此无法通过普通的非限定名称查找找到它们。但是,foo(C) 可以(并且确实)由 ADL 找到,因为 C 是一种类类型。 int 不是,因此不会执行 ADL,并且找不到 foo(int)

关于c++ - 函数重载: builtin vs user defined types,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50923213/

相关文章:

c++ - 如何将 CMake 包含和库添加到 Visual Studio 解决方案?

c++ - 排序对不起作用

c++ - 打印二叉树 - C++

c++ - 如何确定传递给模板函数的 vector 的类型

c# - 定义两个具有相同参数类型的方法

c++ - wchar_t 对字符串的位操作

通用模板 ostream << 运算符的 C++ 不明确重载

c++ - 当当前字符串的长度与前一个字符串的长度相同时,为什么我的字符串连接器发出前一个字符串而不是当前字符串

python - Python 重载装饰器

function - 在 Julia 中定义一个继承自向量的类型