8

假设我有这样的设置:

namespace hi {
    template<typename L, typename R> L operator+(L l, R r) {
        // some body
    }
    auto f() {
        return [] {}; // Legal C++14
    }
}
int main() {
    auto x = hi::f();
    1 + x; // Is this legal?
}

问题是 lambda 类型上的 ADL 是否会按标准在该命名空间中找到重载运算符。

4

2 回答 2

10

C++11 说 (5.1.2, p3) 将声明 lambda 的类型“ in the smallest block scope, class scope, or namespace scope that contains the corresponding lambda-expression.”所以在这种情况下,类型将在f. C++14 的 CD 有相同的语言。

所以问题实际上是本地类的命名空间是什么。我不认为它有一个。

C++11 第 9.8 节 p1 指出:The name of a local class is local to its enclosing scope.因此,我认为它没有任何关联的命名空间(根据 3.4.2,p2),因此不受 ADL 约束。

于 2013-05-25T18:20:39.250 回答
0

§3.4.2/2 说

如果 T 是类类型(包括联合),则其关联的类是:类本身;它所属的类别(如有的话);及其直接和间接基类。其关联名称空间是其关联类是其成员的名称空间。

命名空间关联只穿透一层类嵌套,而不是通过函数范围,如果按字面理解的话。但是 Clang 和 GCC 都允许多个级别的类嵌套,并且 GCC 也使函数范围透明。

在我看来,多层次的类嵌套是一个缺陷,而本地类在 C++11 中是一个疏忽,因为在 C++11 之前,没有办法将本地类从其命名空间中取出——它们不是允许作为模板参数。

于 2013-05-27T13:00:27.183 回答