【问题标题】:Function overloading: builtin vs user defined types函数重载:内置与用户定义类型
【发布时间】:2018-06-19 07:50:41
【问题描述】:
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)”移到模板代码上方,那也可以。怎么回事?

【问题讨论】:

标签: c++ templates overloading


【解决方案1】:

发生了什么事?

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多