有lambda参数时,ADL会失败吗?

时间:2012-03-28 01:15:26

标签: c++ visual-c++ lambda c++11 argument-dependent-lookup

很久以前我注意到在Visual C ++ 10中,当至少有一个参数是lambda时ADL失败了。

std::vector<float> vec;
for_each(begin(vec), end(vec), [](float) {}); 

以上无法在VC ++ 10和11(beta)上编译(通过ADL找到开始和结束)。当我将lambda函数转换为常规自由函数时,事情就像预期的那样工作。

我曾经在Herb Sutters博客上问了一次,并且还阅读了msdn connect上的一些帖子,通常的答案是:这是一个错误,我们还没有实现lambdas的最新标准,但当时 - 这是可以理解的。事情尚未成熟。在MS连接上也有令人不安的评论,即下一版本即vc 11将不会解决这个问题。

我的问题是,此代码预期是否符合C ++ 11标准?我无法理解这一点。当我使用lambdas时,我是否真的必须使用std ::为我的for_each和其他算法添加前缀? 我不知何故怀疑在vc ++ 11发布后这种行为不会改变。

2 个答案:

答案 0 :(得分:15)

该标准不保证您想要它...

考虑到以下因素,我们可以很容易地发现,没有任何保证ADL可以在与您帖子中提供的示例类似的情况下发挥作用。


  • std::begin (c) / std::end (c)

    这些功能在标准中描述如下:

    template <class C> auto begin(C& c) -> decltype(c.begin());
    template <class C> auto end(C& c) -> decltype(c.end());
    

    虽然Container< ... >::iteratorc.begin ()的返回类型)是实现定义的类型。

    有关此事的更多信息,请参阅 24.5.6范围访问 23.3.6.1/2类模板矢量(或任何其他模板STL)容器)。

  • [](){} - Lambda表达式

    lambda是实现定义的类型,标准中没有任何内容表明生成的对象属于 namespace std 下的类型。

    只要它符合标准规定的其他规则,它几乎可以存在于任何地方。



太长;没有阅读

std::begin / std::end / a lambda-expression 产生的类型不能保证在 namespace std 下,因此ADL 保证会开始。

答案 1 :(得分:1)

这是完全有效的代码。任何无错误的编译器都可以编译它。但由于MSVC有bug,所以无法通过ADL搜索函数,那么也许你不应该依赖ADL而是用std::来限定它,帮助编译器找到函数。

相关问题