首页 >后端开发 >C++ >为什么参数依赖查找 (ADL) 在显式实例化函数模板时失败?

为什么参数依赖查找 (ADL) 在显式实例化函数模板时失败?

DDD
DDD原创
2024-12-11 04:20:10564浏览

Why Does Argument Dependent Lookup (ADL) Fail with Explicitly Instantiated Function Templates?

ADL 和函数模板查找

函数模板在 C 编程中发挥着重要作用,可实现代码重用和通用功能。但是,当使用参数依赖查找 (ADL) 在特定命名空间中查找函数模板时,会出现一个微妙的限制。

尝试使用显式模板参数调用函数模板时,该问题就会显现出来,如以下代码所示snippet:

namespace ns {
    struct foo {};
    template<int i> void frob(foo const&amp;) {}
    void non_template(foo const&amp;) {}
}

int main() {
    ns::foo f;
    non_template(f); // This is fine.
    frob<0>(f); // This is not.
}

此失败背后的原因源于 C 标准中的特定条款。根据 C 标准 03 14.8.1.6,在使用显式模板参数调用函数模板时,ADL 不适用,除非具有该名称的函数模板在调用时可见。

在上面的示例中,有当 frob(f); 时,当前作用域中没有可见的名为 frob 的函数模板被称为。因此,ADL 不会被触发,编译器无法找到所需的函数模板。

为了规避这一限制,可以在函数模板之前显式指定命名空间,如下所示:

ns::frob<0>(f);

在这种情况下,ADL 不是必需的,因为函数模板是直接从包含的命名空间调用的。

以下代码示例进一步说明了 ADL 与函数的行为templates:

namespace A {
  struct B { };
  template<int X> void f(B);
}
namespace C {
  template<class T> void f(T t);
}
void g(A::B b) {
  f<3>(b);    //ill-formed: not a function call
  A::f<3>(b); //well-formed
  C::f<3>(b); //ill-formed; argument dependent lookup
              // applies only to unqualified names
  using C::f;
  f<3>(b);    //well-formed because C::f is visible; then
              // A::f is found by argument dependent lookup
}

在这个例子中,函数模板 f 在命名空间 A 和 C 中都被定义。创建完成后,编译器首先检查当前作用域,发现没有可见的 f 模板。然后应用 ADL,但由于 f 是非限定名称,因此它无法在其他命名空间中找到函数模板。

要从命名空间 C 调用模板,必须使用 C::f 或 using 指令显式限定该名称如代码所示。

以上是为什么参数依赖查找 (ADL) 在显式实例化函数模板时失败?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn