ADL doesn't work when there are lambda arguments?

I noticed quite a while ago that in Visual C ++ 10 ADL fails when at least one of the arguments is a lambda.

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

The above cannot be compiled on VC ++ 10 and 11 (beta) (the beginning and the end can be found through ADL). When I convert a lambda function to a regular free function, everything works as expected.

I asked about it once on the Herb Sutters blog, and also read some msdn connection messages, and the usual answers were: this is a mistake, we did not implement the latest lambda standard, but which was understandable at the time, Things were not in baked goods yet form. There were also disturbing comments on MS connect that this would not be allowed for the next version, i.e. vc 11.

My question is, should this code work under the C ++ 11 standard? I canโ€™t figure it out. Do I really need the prefix my for_each and other algorithms with std :: when I use lambdas? I somehow suspect that this behavior will not change after the release of vC ++ 11.

+4
source share
2 answers

This is absolutely correct code. Any compiler without errors can compile it. But since MSVC has an error and therefore cannot search for a function through ADL, you should probably not rely on ADL and qualify it with std:: instead, helping the compiler find that function.

+1
source

The standard does not guarantee what you want.

With this in mind, we can easily understand that there is nothing to guarantee that ADL will work in cases like the one given in your message.


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

    The functions are described in the standard as the following quote:

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

    Although Container< ... >::iterator (which is the return type of c.begin () ) is a type defined for implementation.

    You can read more about this in 24.5.6 Range Access and 23.3.6.1.2 a class template template (or any other STL container template) .sub>

  • [](){} - Lambda expressions

    Lambda is a type defined by an implementation; there is nothing in the standard stating that the resulting object will have a type that is under the std namespace.

    It can largely exist wherever it wants, as long as it confirms the other rules established by the standard.



Too long; Do not read

Types in which std::begin / std::end / a lambda-expression not guaranteed are under the std namespace, so ADL is not guaranteed to click.

+15
source

Source: https://habr.com/ru/post/1403787/


All Articles