[英]ADL fails when there are lambda arguments?
很久以前我注意到在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发布后这种行为不会改变。
该标准不保证您想要它...
考虑到以下因素,我们可以很容易地发现,没有什么能保证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类模板向量 (或任何其他模板STL容器)。
[](){}
- Lambda表达式
lambda是一个实现定义的类型,标准中没有任何内容表明生成的对象将是名称空间std下的类型。
只要它符合标准设定的其他规则,它几乎可以存在于任何需要的地方。
太长; 没看过
std::begin
/ std::end
/ a lambda-expression
产生的类型不能保证在命名空间std下 ,因此不保证ADL会启动。
这是完全有效的代码。 任何无错误的编译器都可以编译它。 但是由于MSVC有bug而且无法通过ADL搜索函数,那么也许你不应该依赖ADL而是用std::
限定它来帮助编译器找到函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.