這個最小的程序lambda表達式,本地類型和全局命名空間
template <typename X>
void foo (X x)
{
bar (x);
}
template <typename X>
void bar (X x)
{
}
int main()
{
foo ([]{});
}
與海灣合作委員會(4.8.5和5.3)編譯和失敗,鐺編譯(3.7)
我的分析如下。
bar
用於foo
並在foo
後聲明,因此它在foo
定義點處不可見。 bar
的唯一方法可以在foo
找到,實例化點是通過參數相關的查找。
foo
和bar
的唯一參數是在main
中定義的lambda。
顯然,gcc將它的類型視爲在全局命名空間中聲明的類型,而clang不是。因此,gcc可以通過ADL找到bar
,並且clang不能。
int main()
{
struct K{};
foo (K()); // gcc compiles, clang complains
}
它看起來像海灣合作委員會是在錯誤的位置:當我們使用main
本地定義的類型
同樣的事情發生。根據標準的lambda類型是未命名的(expr.prim.lambda/3),所以它不應該屬於任何名稱空間。本地類型應該不屬於全局命名空間。
分析是否正確?這是一個已知的gcc錯誤嗎?
這個問題的靈感來自this question。
所以,簡短版本是「本地lambda的類型是否屬於一個命名空間,如果是的話,哪一個呢?」第二個含義是「文件/命名空間/類作用域的lambda類型是否屬於命名空間,如果是,哪一個?」 – Yakk