c++ - 存在 lambda 参数时 ADL 失败?

标签 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(测试版)上编译(开始和结束通过 ADL 找到)。当我将 lambda 函数转换为常规自由函数时,一切都按预期工作。

我曾在 Herb Sutters 博客上询问过一次,还阅读了 msdn connect 上的一些帖子,通常的答案是:这是一个错误,我们还没有实现最新的 lambda 标准,这在当时是可以理解的.事情还没有成型。在 MS connect 上也有令人不安的评论,认为下一个版本(即 vc 11)不会解决这个问题。

我的问题是,这段代码预期可以在 C++11 标准下工作吗?我不太明白。当我使用 lambda 时,我真的必须在我的 for_each 和其他算法前加上 std::前缀吗? 我以某种方式怀疑这种行为在 vc++11 发布后不会改变。

最佳答案

该标准不能保证您希望它达到的效果..

考虑到以下几点,我们可以很容易地意识到,没有什么可以保证 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< ... >::iterator (这是 c.begin () 的返回类型)是一个实现定义类型。

    可以在 24.5.6 Range Access23.3.6.1/2 class template vector(或任何其他模板 STL)中阅读有关此事的更多信息容器)。

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

    lambda 是一种实现定义类型,标准中没有任何内容说明生成的对象将属于命名空间标准 下的类型。 p>

    它几乎可以随心所欲地存在,只要它符合标准设置的其他规则。



太长;没读过

其中的类型std::begin/std::end/ a lambda-expression 产量不能保证低于命名空间标准,因此 ADL 不能保证启动。

关于c++ - 存在 lambda 参数时 ADL 失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9899907/

相关文章:

java - 什么都不做的 Lambda

lambda - 为什么 `let` 不能用于命名内部递归过程?

c++ - std::greater<int>() 和 std::greater<int> 之间的区别?

c++ - GMP(GNU 多精度): "mpz_mod" function error

c++ - 在 Visual C++ 中 switch 是如何编译的,它的优化和速度如何?

c++ - MinGW/GCC 延迟加载 DLL 等价物?

c++ - 与 std::list 相比,push_back 到 std::vector 创建了许多临时对象

c++ - 每帧调用 glGetUniformLocation()

c++ - "position"是 C++ 中的保留字吗?

c++ - lambda 函数返回类型不起作用