在C++中算是一种反向的参数依赖查找

编程语言 2026-07-09

我相当确定我在找的这个特性在C++中并不存在,但也许有一些聪明的替代方案能做出类似的效果。

在C++中,我们具备参数依赖查找(ADL)这一特性,也被称为Koenig查找,例如 这里 有解释。下面是一个例子:

namespace Foo
{
    struct A{};
    void callA(A a) {}
}

int main()
{
    using Foo::A;
    callA(A{}); // OK
}

前些年我也常希望能写出类似的东西,但把函数与它的参数的角色对调:

namespace Foo
{
    class A{};
    void callA(A a) {}
}

int main()
{
    using Foo::callA;
    callA(A{}); // doesn't compile, 'A' is not found
}

直觉上,我觉得 callA 可以在它的参数中找到 Foo::A 的构造函数,因为它们属于 Foo 命名空间。但事实并非如此。

我真正想解决的用例更像是这样的:

#include <vector>
namespace detail
{
    using someCollection = std::vector<int>;
    enum { sorted };
    enum { reversed };
    void iterate(someCollection&);
    void iterate(someCollection&, decltype(sorted));
    void iterate(someCollection&, decltype(reversed));
}
using detail::iterate;

int main()
{
    std::vector<int> v;
    iterate(v); // OK
    iterate(v, sorted); // Error: 'sorted' undefined
    iterate(v, detail::sorted); // OK, but ugly
    using detail::reversed;
    iterate(v, reversed); // OK, but
    auto a = reversed; // I wish to limit the scope of 'reversed'
}

我尝试的是让 enum 值(或者一个 constexpr 常量,或者一个空的 struct)对某个函数调用而言是私有的。在前面的例子中,sortedreversed 只是为了它们各自的唯一类型而存在的占位值。它们只有在调用 iterate 时才有意义,否则就只是在污染全局命名空间。

有何巧妙的变通办法吗?

解决方案

如果你的目标是尽量缩小作用域,你可以通过实际创建一个新的作用域来实现:

int main()
{
    std::vector<int> v;
    {
      using namespace detail;
      iterate(v);
      iterate(v, sorted);
      iterate(v, reversed);
      auto a = reversed;
      // ...
    }
}

这不会把这些名字污染到外部作用域。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章