问题描述
我无法理解基于参数的(Koenig)查找背后的规则。
I'm having trouble understanding the rules behind argument-dependent (Koenig) lookup.
请考虑以下代码:
#include <iostream>
using namespace std;
namespace adl
{
struct Test { };
void foo1(Test const &) { cout << "ADL used (foo1)" << endl; }
void foo2(Test const &) { cout << "ADL used (foo2)" << endl; }
void foo3(Test const &) { cout << "ADL used (foo3)" << endl; }
}
struct foo1
{
foo1() { }
template<class T>
foo1(T const &) { cout << "ADL not used (foo1)" << endl; }
template<class T>
void operator()(T const &) const { cout << "ADL not used (foo3)" << endl; }
};
template<class T> void foo2(T const &)
{ cout << "ADL not used (foo2)" << endl; }
int main()
{
adl::Test t;
foo1 foo3;
(foo1(t));
(foo2(t));
(foo3(t));
}
其输出为:
我希望他们所有人都使用ADL,但令我惊讶的是只有其中一些人使用了。
I expected all of them to use ADL, but I was surprised that only some of them did.
(可能是血腥的,我知道) >详细信息是ADL规则的背后?
我对这个概念已经足够了解了,但是细节是我遇到的麻烦。
What are the (potentially gory, I know) details behind the rules of ADL?
I understand the concept well enough, but the details are what I'm having trouble with.
搜索哪个范围,什么时候搜索它们,什么时候不搜索?
Which scopes are searched, when are they searched, and when are they not searched?
是否有可能不用看就可以判断是否使用了ADL通过 all 在给定代码行之前的 #include
文件?我希望函子和函数在[不]屏蔽ADL方面表现出相同的方式,但是显然它们不一样。
Is it at all possible to tell whether ADL is used without having to look through all the #include
'd files before the given line of code? I expected functors and functions to behave the same way in terms of [not] masking ADL, but apparently they don't.
有什么方法可以 force 如果ADL没有自动完成(例如上述操作)并且您不知道类的名称空间(例如,在模板中),则为
Is there any way to force ADL in cases where it is not done automatically (such as the above) and you don't know the class's namespace (e.g. in a template)?
推荐答案
您的问题并不是与参数相关的查找。首先,依赖参数的查找仅在执行函数的不合格查找时才可能进入画面。调用 foo1(t)
foo1
是一种类型,并调用其模板构造函数。同样, foo3(t)
是合格的查找,因为 foo3
是一个对象,并且在其中调用函数调用运算符对象的类 foo1
。参数查找进入图片的唯一位置是调用 foo2(t)
,在其中查找候选对象:
Your problem isn't really with argument dependent lookup. First of all, argument dependent lookup only possibly enters the picture when doing unqualified looking up of functions. When calling foo1(t)
foo1
is a type and its templated constructor is called. Similarly, foo3(t)
is a qualified lookup because foo3
is an object and the function call operator is looked up in the object's class foo1
. The only place where argument lookup enters the picture is calling foo2(t)
where lookup finds to candidates:
-
:: foo2< adl :: Test>(adl :: Test const&)
-
:: adl :: foo2(adl :: Test const&)
::foo2<adl::Test>(adl::Test const&)
::adl::foo2(adl::Test const&)
这两个函数会移交给重载解决方案,并且由于两个函数都很好地匹配了非模板函数,所以胜出。
These two functions are handed off to overload resolution and since both functions are equally good matches the non-template function wins.
您的问题实际上是三个问题:
Your question are actually three questions:
- 名称查找的细节太广泛了,因此,这个问题是要求撰写一篇我忽略的论文。
- 您的第二个问题扩展为另外三个问题,似乎只有一个相关:
- The gory details of name lookup are too broad and, thus, this question is a request for an essay to be written which I ignore.
- You second question expands to three more questions, only one seems relevant:
- 搜索了哪些范围?在函数定义中查找不合格的函数名称时,规则取决于是否有任何名称是从属名称。如果没有这样的名称(即在非模板代码中或在可以在第一阶段确定名称的模板代码中),则在包含名称空间和与其参数关联的名称空间中查找该名称。否则,只能在关联的命名空间中查找名称。
这篇关于与参数相关的查找-何时完成,搜索什么以及如何强制(或阻止)查找?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!