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?
}

問題は、ラムダ型の ADL が標準によってその名前空間でオーバーロードされた演算子を見つけるかどうかです。

4

2 に答える 2

10

C++11 は (5.1.2, p3) ラムダの型が宣言されると言っています " 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 がクラス型 (共用体を含む) の場合、関連するクラスは次のとおりです。 クラス自体。もしあれば、それがメンバーであるクラス。およびその直接および間接基本クラス。関連する名前空間は、関連するクラスがメンバーになっている名前空間です。

名前空間の関連付けは、文字どおり解釈すると、関数スコープではなく、クラスのネストの 1 つのレベルを通過するだけです。しかし、Clang と GCC はどちらも複数レベルのクラスのネストを許可し、GCC は関数のスコープも透過的にします。

複数レベルのクラスのネストは欠陥であり、ローカル クラスは C++11 の見落としのように見えます。C++11 より前は、ローカル クラスをその名前空間から取り出す方法がなかったからです。そうではありませんでした。テンプレート引数として許可されています。

于 2013-05-27T13:00:27.183 に答える