Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #83572 > unrolled thread

ambiguous reference to 'find' in std and std::ranges namespaces

Started byRalf Goertz <me@myprovider.invalid>
First post2022-04-13 09:58 +0200
Last post2022-04-15 14:39 +0200
Articles 15 — 7 participants

Back to article view | Back to comp.lang.c++


Contents

  ambiguous reference to 'find' in std and std::ranges namespaces Ralf Goertz <me@myprovider.invalid> - 2022-04-13 09:58 +0200
    Re: ambiguous reference to 'find' in std and std::ranges namespaces Paavo Helde <eesnimi@osa.pri.ee> - 2022-04-13 14:27 +0300
      Re: ambiguous reference to 'find' in std and std::ranges namespaces Bo Persson <bo@bo-persson.se> - 2022-04-13 14:21 +0200
        Re: ambiguous reference to 'find' in std and std::ranges namespaces Paavo Helde <eesnimi@osa.pri.ee> - 2022-04-13 15:31 +0300
      Re: ambiguous reference to 'find' in std and std::ranges namespaces Juha Nieminen <nospam@thanks.invalid> - 2022-04-13 13:26 +0000
        Re: ambiguous reference to 'find' in std and std::ranges namespaces Juha Nieminen <nospam@thanks.invalid> - 2022-04-13 13:28 +0000
          Re: ambiguous reference to 'find' in std and std::ranges namespaces Paavo Helde <eesnimi@osa.pri.ee> - 2022-04-13 17:26 +0300
          Re: ambiguous reference to 'find' in std and std::ranges namespaces Christian Gollwitzer <auriocus@gmx.de> - 2022-04-14 07:13 +0200
            Re: ambiguous reference to 'find' in std and std::ranges namespaces Ralf Goertz <me@myprovider.invalid> - 2022-04-14 08:57 +0200
              Re: ambiguous reference to 'find' in std and std::ranges namespaces Bo Persson <bo@bo-persson.se> - 2022-04-14 13:23 +0200
                Re: ambiguous reference to 'find' in std and std::ranges namespaces Paavo Helde <eesnimi@osa.pri.ee> - 2022-04-14 16:32 +0300
                  Re: ambiguous reference to 'find' in std and std::ranges namespaces Bo Persson <bo@bo-persson.se> - 2022-04-14 18:30 +0200
                Re: ambiguous reference to 'find' in std and std::ranges namespaces Ralf Goertz <me@myprovider.invalid> - 2022-04-15 10:14 +0200
              Re: ambiguous reference to 'find' in std and std::ranges namespaces Manfred <noname@add.invalid> - 2022-04-14 15:02 +0200
    Re: ambiguous reference to 'find' in std and std::ranges namespaces Christian Hanné <the.hanne@gmail.com> - 2022-04-15 14:39 +0200

#83572 — ambiguous reference to 'find' in std and std::ranges namespaces

FromRalf Goertz <me@myprovider.invalid>
Date2022-04-13 09:58 +0200
Subjectambiguous reference to 'find' in std and std::ranges namespaces
Message-ID<t35vs1$8pu$1@dont-email.me>
Hi,

why do I get the error (with gcc-Version 11.2.1):


find_test.cc: In function ‘int main()’:
find_test.cc:10:41: error: reference to ‘find’ is ambiguous
   10 |     std::vector<int>::const_iterator it=find(v,47);
      |                                         ^~~~

when compiling the following code:

#include <algorithm>
#include <ranges>
#include <vector>

using namespace std;         // *
using namespace std::ranges; // **

int main() {
    const std::vector<int> v({47,11});
    std::vector<int>::const_iterator it=find(v,47);
}

AFAICT there is no way that std::find could be a candidate whereas
std::ranges::find matches. This can also be seen by the fact that
commenting out the line marked * results in successful compilation but
commenting out ** instead leaves me with the error of no matching
function. 

PS: Please don't bother to comment the "using namespace" directives,
these are not the point and I know they are frowned upon.

[toc] | [next] | [standalone]


#83573

FromPaavo Helde <eesnimi@osa.pri.ee>
Date2022-04-13 14:27 +0300
Message-ID<t36c3i$dpq$1@dont-email.me>
In reply to#83572
13.04.2022 10:58 Ralf Goertz kirjutas:
> Hi,
> 
> why do I get the error (with gcc-Version 11.2.1):
> 
> 
> find_test.cc: In function ‘int main()’:
> find_test.cc:10:41: error: reference to ‘find’ is ambiguous
>     10 |     std::vector<int>::const_iterator it=find(v,47);
>        |                                         ^~~~
> 
> when compiling the following code:
> 
> #include <algorithm>
> #include <ranges>
> #include <vector>
> 
> using namespace std;         // *
> using namespace std::ranges; // **
> 
> int main() {
>      const std::vector<int> v({47,11});
>      std::vector<int>::const_iterator it=find(v,47);
> }

Most probably this is because std::ranges::find is not a function 
template, but something called "niebloid", to disable ADL 
("https://en.cppreference.com/w/cpp/algorithm/ranges/find").

In my implementation it appears to be implemented as a function object, 
having operator() member functions. I guess the problem is caused by 
this specific implementation, as the whole point of niebloids seems to 
be the opposite (avoiding clashes with the std:: namespace).

> AFAICT there is no way that std::find could be a candidate whereas
> std::ranges::find matches. 

I guess the compiler never gets so far as to consider template overload 
candidates.

[toc] | [prev] | [next] | [standalone]


#83574

FromBo Persson <bo@bo-persson.se>
Date2022-04-13 14:21 +0200
Message-ID<jbntipF5or8U1@mid.individual.net>
In reply to#83573
On 2022-04-13 at 13:27, Paavo Helde wrote:
> 13.04.2022 10:58 Ralf Goertz kirjutas:
>> Hi,
>>
>> why do I get the error (with gcc-Version 11.2.1):
>>
>>
>> find_test.cc: In function ‘int main()’:
>> find_test.cc:10:41: error: reference to ‘find’ is ambiguous
>>     10 |     std::vector<int>::const_iterator it=find(v,47);
>>        |                                         ^~~~
>>
>> when compiling the following code:
>>
>> #include <algorithm>
>> #include <ranges>
>> #include <vector>
>>
>> using namespace std;         // *
>> using namespace std::ranges; // **
>>
>> int main() {
>>      const std::vector<int> v({47,11});
>>      std::vector<int>::const_iterator it=find(v,47);
>> }
> 
> Most probably this is because std::ranges::find is not a function 
> template, but something called "niebloid", to disable ADL 
> ("https://en.cppreference.com/w/cpp/algorithm/ranges/find").
> 
> In my implementation it appears to be implemented as a function object, 
> having operator() member functions. I guess the problem is caused by 
> this specific implementation, as the whole point of niebloids seems to 
> be the opposite (avoiding clashes with the std:: namespace).

That works from *inside* the ranges namespace. Once an object is found, 
the compiler knows not to do ADL, because that's only for functions.

> 
>> AFAICT there is no way that std::find could be a candidate whereas
>> std::ranges::find matches. 
> 
> I guess the compiler never gets so far as to consider template overload 
> candidates.

It cannot do that when the candidates are not all functions. There are 
no overload rules for objects (like niebloids).

[toc] | [prev] | [next] | [standalone]


#83575

FromPaavo Helde <eesnimi@osa.pri.ee>
Date2022-04-13 15:31 +0300
Message-ID<t36fq7$ap9$1@dont-email.me>
In reply to#83574
13.04.2022 15:21 Bo Persson kirjutas:
> On 2022-04-13 at 13:27, Paavo Helde wrote:
>> 13.04.2022 10:58 Ralf Goertz kirjutas:
>>> Hi,
>>>
>>> why do I get the error (with gcc-Version 11.2.1):
>>>
>>>
>>> find_test.cc: In function ‘int main()’:
>>> find_test.cc:10:41: error: reference to ‘find’ is ambiguous
>>>     10 |     std::vector<int>::const_iterator it=find(v,47);
>>>        |                                         ^~~~
>>>
>>> when compiling the following code:
>>>
>>> #include <algorithm>
>>> #include <ranges>
>>> #include <vector>
>>>
>>> using namespace std;         // *
>>> using namespace std::ranges; // **
>>>
>>> int main() {
>>>      const std::vector<int> v({47,11});
>>>      std::vector<int>::const_iterator it=find(v,47);
>>> }
>>
>> Most probably this is because std::ranges::find is not a function 
>> template, but something called "niebloid", to disable ADL 
>> ("https://en.cppreference.com/w/cpp/algorithm/ranges/find").
>>
>> In my implementation it appears to be implemented as a function 
>> object, having operator() member functions. I guess the problem is 
>> caused by this specific implementation, as the whole point of 
>> niebloids seems to be the opposite (avoiding clashes with the std:: 
>> namespace).
> 
> That works from *inside* the ranges namespace. Once an object is found, 
> the compiler knows not to do ADL, because that's only for functions.
> 
>>
>>> AFAICT there is no way that std::find could be a candidate whereas
>>> std::ranges::find matches. 
>>
>> I guess the compiler never gets so far as to consider template 
>> overload candidates.
> 
> It cannot do that when the candidates are not all functions. There are 
> no overload rules for objects (like niebloids).

The cppreference page talks about the possibility of implementing the 
niebloids by special compiler extensions instead of function objects. 
Not sure if/how this would affect the lookup rules.

[toc] | [prev] | [next] | [standalone]


#83576

FromJuha Nieminen <nospam@thanks.invalid>
Date2022-04-13 13:26 +0000
Message-ID<t36j2i$10a3$1@gioia.aioe.org>
In reply to#83573
Paavo Helde <eesnimi@osa.pri.ee> wrote:
> In my implementation it appears to be implemented as a function object, 
> having operator() member functions. I guess the problem is caused by 
> this specific implementation, as the whole point of niebloids seems to 
> be the opposite (avoiding clashes with the std:: namespace).

Perhaps a minimal example that replicates the mentioned behavior could
illuminate if this is normal to-be-expected behavior, a problem with
the library implementation, or perhaps even a problem with the compiler
itself.

[toc] | [prev] | [next] | [standalone]


#83577

FromJuha Nieminen <nospam@thanks.invalid>
Date2022-04-13 13:28 +0000
Message-ID<t36j5k$10a3$2@gioia.aioe.org>
In reply to#83576
Juha Nieminen <nospam@thanks.invalid> wrote:
> Paavo Helde <eesnimi@osa.pri.ee> wrote:
>> In my implementation it appears to be implemented as a function object, 
>> having operator() member functions. I guess the problem is caused by 
>> this specific implementation, as the whole point of niebloids seems to 
>> be the opposite (avoiding clashes with the std:: namespace).
> 
> Perhaps a minimal example that replicates the mentioned behavior could
> illuminate if this is normal to-be-expected behavior, a problem with
> the library implementation, or perhaps even a problem with the compiler
> itself.

(I mean a minimal example that doesn't use the standard library,
ie. a piece of code that itself demonstrates what's happening inside
the library for this error to happen.)

[toc] | [prev] | [next] | [standalone]


#83578

FromPaavo Helde <eesnimi@osa.pri.ee>
Date2022-04-13 17:26 +0300
Message-ID<t36mim$25k$1@dont-email.me>
In reply to#83577
13.04.2022 16:28 Juha Nieminen kirjutas:
> Juha Nieminen <nospam@thanks.invalid> wrote:
>> Paavo Helde <eesnimi@osa.pri.ee> wrote:
>>> In my implementation it appears to be implemented as a function object,
>>> having operator() member functions. I guess the problem is caused by
>>> this specific implementation, as the whole point of niebloids seems to
>>> be the opposite (avoiding clashes with the std:: namespace).
>>
>> Perhaps a minimal example that replicates the mentioned behavior could
>> illuminate if this is normal to-be-expected behavior, a problem with
>> the library implementation, or perhaps even a problem with the compiler
>> itself.
> 
> (I mean a minimal example that doesn't use the standard library,
> ie. a piece of code that itself demonstrates what's happening inside
> the library for this error to happen.)

Here you are:

namespace A {
    template<typename T> void foo(T, T, T) {}
}

namespace B {
     struct C {
         void operator()(int) {}
     } foo;
}

using namespace A;
using namespace B;

int main() {
     foo(1);
}

ConsoleTestVS2019.cpp(15,8): error C2872: 'foo': ambiguous symbol
ConsoleTestVS2019.cpp(2,30): message : could be 'void A::foo(T,T,T)'
ConsoleTestVS2019.cpp(8,7): message : or       'B::C B::foo'
ConsoleTestVS2019.cpp(15,5): error C2672: 'A::foo': no matching 
overloaded function found
ConsoleTestVS2019.cpp(15,10): error C2780: 'void A::foo(T,T,T)': expects 
3 arguments - 1 provided
ConsoleTestVS2019.cpp(2): message : see declaration of 'A::foo'

[toc] | [prev] | [next] | [standalone]


#83579

FromChristian Gollwitzer <auriocus@gmx.de>
Date2022-04-14 07:13 +0200
Message-ID<t38aik$me1$1@dont-email.me>
In reply to#83577
Am 13.04.22 um 15:28 schrieb Juha Nieminen:
> Juha Nieminen <nospam@thanks.invalid> wrote:
>> Paavo Helde <eesnimi@osa.pri.ee> wrote:
>>> In my implementation it appears to be implemented as a function object,
>>> having operator() member functions. I guess the problem is caused by
>>> this specific implementation, as the whole point of niebloids seems to
>>> be the opposite (avoiding clashes with the std:: namespace).
>>
>> Perhaps a minimal example that replicates the mentioned behavior could
>> illuminate if this is normal to-be-expected behavior, a problem with
>> the library implementation, or perhaps even a problem with the compiler
>> itself.
> 
> (I mean a minimal example that doesn't use the standard library,
> ie. a piece of code that itself demonstrates what's happening inside
> the library for this error to happen.)

Maybe the second example in this answer is helpful:
	
	https://stackoverflow.com/a/62929027

Christian

[toc] | [prev] | [next] | [standalone]


#83581

FromRalf Goertz <me@myprovider.invalid>
Date2022-04-14 08:57 +0200
Message-ID<t38gk5$lev$1@dont-email.me>
In reply to#83579
Am Thu, 14 Apr 2022 07:13:55 +0200
schrieb Christian Gollwitzer <auriocus@gmx.de>:

> Am 13.04.22 um 15:28 schrieb Juha Nieminen:
> > Juha Nieminen <nospam@thanks.invalid> wrote:  
> >> Paavo Helde <eesnimi@osa.pri.ee> wrote:  
> >>> In my implementation it appears to be implemented as a function
> >>> object, having operator() member functions. I guess the problem
> >>> is caused by this specific implementation, as the whole point of
> >>> niebloids seems to be the opposite (avoiding clashes with the
> >>> std:: namespace).  
> >>
> >> Perhaps a minimal example that replicates the mentioned behavior
> >> could illuminate if this is normal to-be-expected behavior, a
> >> problem with the library implementation, or perhaps even a problem
> >> with the compiler itself.  
> > 
> > (I mean a minimal example that doesn't use the standard library,
> > ie. a piece of code that itself demonstrates what's happening inside
> > the library for this error to happen.)  
> 
> Maybe the second example in this answer is helpful:
> 	
> 	https://stackoverflow.com/a/62929027

I have to admit that I am now more confused than before. Is the lookup
problem in my OP a bug or not? And if not and the niebloids are there to
avoid clashes why don't they do their job in my case? The first example
in the cited answer is equivalent to 

find(begin(v), end(v), 47)

in my OP. This works with either "using" directive but not both which I
understand since the iterator variant of find is declared in both. But
with my original "find" there should be no clash since nothing in std::
matches.

[toc] | [prev] | [next] | [standalone]


#83582

FromBo Persson <bo@bo-persson.se>
Date2022-04-14 13:23 +0200
Message-ID<jbqehlFko73U1@mid.individual.net>
In reply to#83581
On 2022-04-14 at 08:57, Ralf Goertz wrote:
> Am Thu, 14 Apr 2022 07:13:55 +0200
> schrieb Christian Gollwitzer <auriocus@gmx.de>:
> 
>> Am 13.04.22 um 15:28 schrieb Juha Nieminen:
>>> Juha Nieminen <nospam@thanks.invalid> wrote:
>>>> Paavo Helde <eesnimi@osa.pri.ee> wrote:
>>>>> In my implementation it appears to be implemented as a function
>>>>> object, having operator() member functions. I guess the problem
>>>>> is caused by this specific implementation, as the whole point of
>>>>> niebloids seems to be the opposite (avoiding clashes with the
>>>>> std:: namespace).
>>>>
>>>> Perhaps a minimal example that replicates the mentioned behavior
>>>> could illuminate if this is normal to-be-expected behavior, a
>>>> problem with the library implementation, or perhaps even a problem
>>>> with the compiler itself.
>>>
>>> (I mean a minimal example that doesn't use the standard library,
>>> ie. a piece of code that itself demonstrates what's happening inside
>>> the library for this error to happen.)
>>
>> Maybe the second example in this answer is helpful:
>> 	
>> 	https://stackoverflow.com/a/62929027
> 
> I have to admit that I am now more confused than before. Is the lookup
> problem in my OP a bug or not? And if not and the niebloids are there to
> avoid clashes why don't they do their job in my case? The first example
> in the cited answer is equivalent to
> 
> find(begin(v), end(v), 47)
> 
> in my OP. This works with either "using" directive but not both which I
> understand since the iterator variant of find is declared in both. But
> with my original "find" there should be no clash since nothing in std::
> matches.
> 

The niebloids suppress ADL by not being functions. Only functions have 
overloads to be resolved.

The name "find" is present in the code, not by being found by ADL, but 
by being explictly brought in by the "using namespace" directives.

To do an overloads resolution (to see if anything "matches"), the 
compiler *first* collects eveything with the correct name, and *then* 
tries to see if one overload is better than all the others. Only then 
does it consider the types and numbers of parameters.

Now, with the niebloid in the set, this all fails as one of the "find" 
items is not a function. And only functions have overloads.


So we seem to have found another reason for why "using namespace std;" 
is ungood.

[toc] | [prev] | [next] | [standalone]


#83584

FromPaavo Helde <eesnimi@osa.pri.ee>
Date2022-04-14 16:32 +0300
Message-ID<t397pk$v77$1@dont-email.me>
In reply to#83582
14.04.2022 14:23 Bo Persson kirjutas:

> 
> The niebloids suppress ADL by not being functions. Only functions have 
> overloads to be resolved.

Yes, the OP problems are because niebloids are not functions. The 
question is whether this is an implementation artifact or is this 
inevitable?

IOW, if niebloids were implemented as "functions without ADL" by a 
compiler extension, would this be standard compliant and would this 
solve OP problems?

[toc] | [prev] | [next] | [standalone]


#83585

FromBo Persson <bo@bo-persson.se>
Date2022-04-14 18:30 +0200
Message-ID<jbr0glFo4ogU1@mid.individual.net>
In reply to#83584
On 2022-04-14 at 15:32, Paavo Helde wrote:
> 14.04.2022 14:23 Bo Persson kirjutas:
> 
>>
>> The niebloids suppress ADL by not being functions. Only functions have 
>> overloads to be resolved.
> 
> Yes, the OP problems are because niebloids are not functions. The 
> question is whether this is an implementation artifact or is this 
> inevitable?
> 
> IOW, if niebloids were implemented as "functions without ADL" by a 
> compiler extension, would this be standard compliant and would this 
> solve OP problems?

Who knows what an extension would do?  :-)

However, the problem here isn't ADL but that std::find is found 
*without* using ADL. It is just visible anyway, due to the "using".

[toc] | [prev] | [next] | [standalone]


#83587

FromRalf Goertz <me@myprovider.invalid>
Date2022-04-15 10:14 +0200
Message-ID<t3b9gu$l00$1@dont-email.me>
In reply to#83582
Am Thu, 14 Apr 2022 13:23:33 +0200
schrieb Bo Persson <bo@bo-persson.se>:

> On 2022-04-14 at 08:57, Ralf Goertz wrote:
> >   
> > I have to admit that I am now more confused than before. Is the
> > lookup problem in my OP a bug or not? And if not and the niebloids
> > are there to avoid clashes why don't they do their job in my case?
> > The first example in the cited answer is equivalent to
> > 
> > find(begin(v), end(v), 47)
> > 
> > in my OP. This works with either "using" directive but not both
> > which I understand since the iterator variant of find is declared
> > in both. But with my original "find" there should be no clash since
> > nothing in std:: matches.
> >   
> 
> The niebloids suppress ADL by not being functions. Only functions
> have overloads to be resolved.
> 
> The name "find" is present in the code, not by being found by ADL,
> but by being explictly brought in by the "using namespace" directives.
> 
> To do an overloads resolution (to see if anything "matches"), the 
> compiler *first* collects eveything with the correct name, and *then* 
> tries to see if one overload is better than all the others. Only then 
> does it consider the types and numbers of parameters.
> 
> Now, with the niebloid in the set, this all fails as one of the
> "find" items is not a function. And only functions have overloads.

Given the fact that iterator versions (I don't know if all the versions
in std) of "find" are also present in std::ranges, couldn't the range
versions have been put in std as well so that we just have another
version of "find" in std? It has been done before, hasn't it?

> So we seem to have found another reason for why "using namespace
> std;" is ungood.

Apparently.

[toc] | [prev] | [next] | [standalone]


#83583

FromManfred <noname@add.invalid>
Date2022-04-14 15:02 +0200
Message-ID<t3961a$1bn6$1@gioia.aioe.org>
In reply to#83581
On 4/14/2022 8:57 AM, Ralf Goertz wrote:
> I have to admit that I am now more confused than before.

Welcome to modern C++ :D

[toc] | [prev] | [next] | [standalone]


#83588

FromChristian Hanné <the.hanne@gmail.com>
Date2022-04-15 14:39 +0200
Message-ID<t3bp19$1v9q$1@gioia.aioe.org>
In reply to#83572
find() has some bugs until C++17.
Better try C++20.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c++


csiph-web