很久以前,我注意到在 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 Access 和 23.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/