Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ADL fails when there are lambda arguments?

quite some time ago i noticed 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 fails to compile on VC++10 and 11 (beta) (begin and end are found via ADL). When i convert the lambda function into a regular free function things work just as expected.

I've asked on Herb Sutters blog once and also read some posts on msdn connect and the usual answers were: this is a bug, we havent implemented the latest standard of the lambdas yet which - at that time - was quite understandable. Things haven't been in a baked form yet. On MS connect there have also been disturbing comments that this will not be resolved for the next release i.e. vc 11.

My question is, is this code expected to work under the C++11 standard? I cant quite figure that out. Do i really have to prefix my for_each and other algorithms with std:: when I'm using lambdas? I somehow suspect that this behavior will not change after vc++11 release.

like image 739
Martin Wirth Avatar asked Dec 04 '22 17:12

Martin Wirth


2 Answers

The standard doesn't guarantee what you'd want it to..

With the below in mind we can easily realize that there is nothing guaranteeing that ADL would work in cases similar to the example provided in your post.


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

    The functions are described in the standard as the below quotation:

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

    Though the Container< ... >::iterator (which is the return-type of c.begin ()) is an implementation-defined type.

    More about the matter can be read upon at 24.5.6 Range Access, and 23.3.6.1/2 class template vector (or any other template STL container).

  • [](){} - Lambda Expressions

    A lambda is an implementation-defined type, there is nothing in the standard stating that the resulting object will be of a type which is under namespace std.

    It can pretty much exists wherever it wants, as long as it confirms to the other rules set up by the standard.



Too Long; Didn't Read

The types of which std::begin/std::end/a lambda-expression yields are not guaranteed to be under namespace std, therefore ADL is not guaranteed to kick in.

like image 63
Filip Roséen - refp Avatar answered Dec 09 '22 16:12

Filip Roséen - refp


That is perfectly valid code. Any bug-free compiler will be able to compile it. But since MSVC has bug and so is unable to search the function through ADL, then maybe you should not rely on ADL and instead qualify it with std:: helping the compiler to find the function.

like image 32
Nawaz Avatar answered Dec 09 '22 15:12

Nawaz