- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
关于什么是参数依赖查找有哪些好的解释?许多人也将其称为 Koenig Lookup。
最好我想知道:
最佳答案
Koenig 查找,或 Argument Dependent Lookup ,描述了编译器如何在 C++ 中查找非限定名称。
C++11 标准 § 3.4.2/1 指出:
When the postfix-expression in a function call (5.2.2) is an unqualified-id, other namespaces not considered during the usual unqualified lookup (3.4.1) may be searched, and in those namespaces, namespace-scope friend function declarations (11.3) not otherwise visible may be found. These modifications to the search depend on the types of the arguments (and for template template arguments, the namespace of the templateargument).
简单来说,Nicolai Josuttis 说1:
You don’t have to qualify the namespace for functions if one or more argument types are defined in the namespace of the function.
一个简单的代码示例:
namespace MyNamespace
{
class MyClass {};
void doSomething(MyClass) {}
}
MyNamespace::MyClass obj; // global object
int main()
{
doSomething(obj); // Works Fine - MyNamespace::doSomething() is called.
}
在上面的例子中,既没有using
声明也没有using
指令,但编译器仍然正确识别了非限定名称doSomething()
作为在命名空间 MyNamespace
中通过应用 Koenig 查找 声明的函数。
该算法告诉编译器不仅要查看本地范围,还要查看包含参数类型的命名空间。因此,在上面的代码中,编译器发现对象 obj
,即函数 doSomething()
的参数,属于命名空间 MyNamespace
。因此,它查看该命名空间以找到 doSomething()
的声明。
如上面的简单代码示例所示,Koenig 查找为程序员提供了便利和易用性。如果没有 Koenig 查找,程序员将需要重复指定完全限定名称,或者使用大量 using
声明。
过度依赖 Koenig 查找会导致语义问题,有时会让程序员措手不及。
考虑 std::swap
的例子,这是交换两个值的标准库算法。使用 Koenig 查找时,在使用此算法时必须谨慎,因为:
std::swap(obj1,obj2);
可能不会表现出与以下相同的行为:
using std::swap;
swap(obj1, obj2);
使用 ADL,调用哪个版本的 swap
函数将取决于传递给它的参数的命名空间。
如果存在命名空间 A
,并且如果 A::obj1
、A::obj2
和 A::swap()
存在,那么第二个示例将导致调用 A::swap()
,这可能不是用户想要的。
此外,如果由于某种原因 A::swap(A::MyClass&, A::MyClass&)
和 std::swap(A::MyClass&, A::MyClass& )
被定义,那么第一个示例将调用 std::swap(A::MyClass&, A::MyClass&)
但第二个不会编译,因为 swap(obj1, obj2)
会产生歧义。
因为它是由前 AT&T 和贝尔实验室研究员和程序员设计的, Andrew Koenig .
标准 C++03/11 [basic.lookup.argdep]:3.4.2 参数相关名称查找。
关于c++ - 什么是 "Argument-Dependent Lookup"(又名 ADL,或 "Koenig Lookup")?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49775595/
这个问题在这里已经有了答案: How do I write an ADL-enabled trailing return type, or noexcept specification? (4 个答
例如,我想使用约束来确保函数 isinf为模板参数实现 T .如 T是 float 之一, double , long double或整数类型,这可以通过以下方式完成: #include templ
我在 ADF 中进行自定义事件,其中涉及从 Azure 存储 Blob 读取多个文件,对它们进行一些处理,然后最终将生成的文件写入 Azure Data Lake Store。最后一步是我停止的地方,
我遇到了以下涉及 ADL 和已删除函数的令人困惑的示例: 第一个例子: namespace A { struct S{}; void f(S){cout << "adl" << end
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and th
template struct S { bool valid(T a) { return is_valid(a); } }; bool is_valid(int) { return t
我有几个命名空间,每个命名空间都有一个名为 f 的函数模板。 // f() and Widget namespace A { struct Widget { }; template vo
我有一个带有类内定义友元函数的类,我最好不要修改它(它来自已经部署的 header ) #include #include namespace our_namespace { template
我有一个函数模板 printSize 在声明 getSize 之前调用重载函数 getSize。为了让我的程序结构更清晰,我想将两个函数放在不同的命名空间 A 和 B 中,如注释代码行所示。但是,AD
struct S { vector v; void method() { begin(v); } }; 上面的代码片段编译正常,因为 ADL直到我添加
对于非限定名称查找,“通常非限定名称查找”和“参数相关名称查找”(ADL),我无法在标准中找到哪一个先发生? 再次尝试向过载候选集添加一些内容,但顺序似乎并不重要。但仍然很高兴知道哪一个先发生。 谢谢
我试图了解如何 ADL至少它的基础是有效的,并创建了以下代码: #include #include #include using std::pair; using std::string; u
简而言之,我试图了解 C++ 中参数依赖查找的行为。我不清楚 ISO/IEC 14882:2017 (E) 中关于 ADL 的一些陈述。我希望有人能向我澄清它们。 按照标准, Typedef name
可以给我一个不使用模板的 ADL 示例吗?从来没有见过这样的东西。我的意思是像 here .具体来说,我对导致上述一些陷阱的示例感兴趣。 编辑: 我认为 Tomalak 的回答可以延伸到陷阱。考虑一下
有3个例子: 我. typedef int foo; namespace B { struct S { operator int(){ return 24; }
我正在使用 Visual Studio 2010 在 Microsoft Windows 7 上编译 x64 服务,使用 Boost variant像这样的东西: namespace my_ns {
情况是某些成员函数 bar::Bar::frobnicate 想要利用 ADL 在具有相同名称的函数中从某个未知命名空间中查找函数。但是,它只能找到自己的名字。 测试用例 (请注意,实际上,Bar 是
我对 C++ 中的标准 ADL 解析有疑问。 这是解释我的查询的示例代码: #include // The mechanism: namespace A { template ::std::st
这是来自 Does argument dependent lookup only search namespaces or classes too? 的跟进问题,其中@David Rodríguez
这个问题在这里已经有了答案: Why doesn't ADL find function templates? (4 个答案) 关闭 8 年前。 我想明白为什么调用模板f下面不编译: struct
我是一名优秀的程序员,十分优秀!