在C++中算是一种反向的参数依赖查找
我相当确定我在找的这个特性在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)对某个函数调用而言是私有的。在前面的例子中,sorted 和 reversed 只是为了它们各自的唯一类型而存在的占位值。它们只有在调用 iterate 时才有意义,否则就只是在污染全局命名空间。
有何巧妙的变通办法吗?
解决方案
如果你的目标是尽量缩小作用域,你可以通过实际创建一个新的作用域来实现:
int main()
{
std::vector<int> v;
{
using namespace detail;
iterate(v);
iterate(v, sorted);
iterate(v, reversed);
auto a = reversed;
// ...
}
}
这不会把这些名字污染到外部作用域。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。