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

Mar*_*rth 4 c++ lambda visual-c++ argument-dependent-lookup c++11

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

std::vector<float> vec;
for_each(begin(vec), end(vec), [](float) {}); 
Run Code Online (Sandbox Code Playgroud)

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

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

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

Fil*_*efp 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());
    
    Run Code Online (Sandbox Code Playgroud)

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

    有关此问题的更多信息,请参阅24.5.6 Range Access23.3.6.1/2类模板向量(或任何其他模板STL容器).

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

    lambda是一个实现定义的类型,标准中没有任何内容表明生成的对象将是名称空间std下的类型.

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



太长; 没看过

其中std::begin/ std::end/ a lambda-expressionyield 的类型不保证在命名空间std下,因此保证ADL 可以启动.

  • @David:不,问题正是关于`for_each`.它甚至说"开始"和"结束"都没有问题.我想大多数人都没有正确地阅读这个问题.对于refp:+1,这是正确的答案. (3认同)