C++ ADL是否与命名的lambdas一起工作?

C++ ADL是否与命名的lambdas一起工作?,c++,c++11,lambda,argument-dependent-lookup,C++,C++11,Lambda,Argument Dependent Lookup,假设我在一个名称空间中有一个类和一个命名的lambda namespace bla { class X { /* ... */ }; static auto lambda = []( X param ){ /* ... */ }; } 此lambda几乎等同于已内联声明的函数。但是我可以从另一个不相关的名称空间调用lambda,而不用使用ADL(参数相关查找,也称为Koenig查找)提及名称空间bla lambda不是函数,而是可以像函数一样调用的对象。因此,它没有得到函数处理

假设我在一个名称空间中有一个类和一个命名的lambda

namespace bla {
    class X { /* ... */ };
    static auto lambda = []( X param ){ /* ... */ };
}
此lambda几乎等同于已内联声明的函数。但是我可以从另一个不相关的名称空间调用lambda,而不用使用ADL(参数相关查找,也称为Koenig查找)提及名称空间
bla


lambda不是函数,而是可以像函数一样调用的对象。因此,它没有得到函数处理,其调用也不受ADL的约束。

lambda不是函数,而是可以像函数一样调用的对象。因此,它没有得到函数处理,其调用也不受ADL的约束。

lambda实际上是一个对象,因此问题实际上归结为:

ADL对对象有效吗

显而易见的答案是,它不会,ADL只会为重载解决方案的候选集添加函数。还请注意,如果常规查找发现函数以外的任何内容,则ADL不会向重载解析集添加任何候选项

namespace A {
   struct S { operator int() const { return 0; } };
   void f(S const &) { std::cout << "A::f\n"; }
}
auto f = [](int) { std::cout << "lambda\n"; }
namespace B {
   void test() {
      ::A::S s;
      f(s);      // prints lambda
   }
}
名称空间A{
结构S{operator int()常量{return 0;};

void f(S const&{std::coutlambda实际上是一个对象,所以问题可以归结为:

ADL对对象有效吗

显而易见的答案是没有,ADL只会向重载解析候选集添加函数。还要注意,如果常规查找发现函数以外的任何内容,则ADL不会向重载解析集添加任何候选

namespace A {
   struct S { operator int() const { return 0; } };
   void f(S const &) { std::cout << "A::f\n"; }
}
auto f = [](int) { std::cout << "lambda\n"; }
namespace B {
   void test() {
      ::A::S s;
      f(s);      // prints lambda
   }
}
名称空间A{
结构S{operator int()常量{return 0;};

空f(S常数&){std::cout@jrok:不,lambda和polymophic函数包装器
std::function
是完全正交和独立的概念。不过,我很傻。这里是33C:)@Andy:不是。这个建议涵盖了lambda对象本身在函数范围内作为ADL参数传递,而不是ADL调用这样的lambda.Since这是对所有答案的评论(或我对所有答案的评论),我把它放在这里:我发现了将ADL限制在函数和函数模板上的文本。所以我的评论是错误的,我对此表示道歉。@jrok:不,lambda和polymophic函数包装器
std::function
是完全正交和独立的概念。别担心,我太傻了。这里的阴影是33C:)@Andy:不是。那是oposal在函数作用域中将lambda对象本身作为ADL参数传递,而不是用于调用此类lambda的ADL,我会把它放在这里:我找到了将ADL限制为函数和函数模板的文本。因此,我的注释是错误的,我对此表示道歉。这是错误的。名称是否受ADL约束取决于使用时的语法。如果语法是函数调用的语法,则ADL起作用。(另一方面,ADL永远找不到类成员.Period。无论其类型如何。)我之前的评论完全错误,但使用的措辞仍然具有误导性。只要有具有函数调用语法的表达式,ADL就会介入。但ADL只会“查找”函数和函数模板。这是不正确的。名称是否受ADL约束取决于使用时的语法。如果语法是函数调用的语法,则ADL起作用。(另一方面,ADL永远找不到类成员。句点。无论其类型如何。)我之前的评论是完全错误的,但是使用的措辞仍然是误导性的。ADL会在任何时候使用带有函数调用语法的表达式。但是ADL只会“查找”函数和函数模板。这从根本上说是错误的。ADL涉及名称查找,并且独立于名称绑定到的实体。ADL在调用站点被触发,因为表达式具有函数调用语法。但是,如果非限定名称查找发现既不是函数也不是函数的声明,则不会触发ADLr是一个函数模板。(我简化了一点,但这是这里的相关部分。)我之前的评论完全错误,David(几乎)是对的。(我说几乎,因为ADL也会找到函数模板,而不仅仅是函数。)我对他的例子的评论仍然有效——在本例中,没有ADL,因为在非限定名称查找期间发现了一个非函数。这是两个独立的问题。这从根本上说是错误的。ADL涉及名称查找,并且独立于名称绑定到的实体。ADL在调用站点被以下事实触发:表达式具有函数调用语法。但如果非限定名称查找发现既不是函数也不是函数模板的声明,则不会触发ADL。(我简化了一点,但这是此处的相关部分。)我之前的评论完全错误,David(几乎)是对的。(我说几乎,因为ADL也会找到函数模板,而不仅仅是函数。)我对他的例子的评论仍然有效——在本例中,没有ADL,因为在非限定名称查找过程中发现了非函数。这是两个独立的问题。