Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #83572 > unrolled thread
| Started by | Ralf Goertz <me@myprovider.invalid> |
|---|---|
| First post | 2022-04-13 09:58 +0200 |
| Last post | 2022-04-15 14:39 +0200 |
| Articles | 15 — 7 participants |
Back to article view | Back to comp.lang.c++
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
| From | Ralf Goertz <me@myprovider.invalid> |
|---|---|
| Date | 2022-04-13 09:58 +0200 |
| Subject | ambiguous 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]
| From | Paavo Helde <eesnimi@osa.pri.ee> |
|---|---|
| Date | 2022-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]
| From | Bo Persson <bo@bo-persson.se> |
|---|---|
| Date | 2022-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]
| From | Paavo Helde <eesnimi@osa.pri.ee> |
|---|---|
| Date | 2022-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]
| From | Juha Nieminen <nospam@thanks.invalid> |
|---|---|
| Date | 2022-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]
| From | Juha Nieminen <nospam@thanks.invalid> |
|---|---|
| Date | 2022-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]
| From | Paavo Helde <eesnimi@osa.pri.ee> |
|---|---|
| Date | 2022-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]
| From | Christian Gollwitzer <auriocus@gmx.de> |
|---|---|
| Date | 2022-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]
| From | Ralf Goertz <me@myprovider.invalid> |
|---|---|
| Date | 2022-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]
| From | Bo Persson <bo@bo-persson.se> |
|---|---|
| Date | 2022-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]
| From | Paavo Helde <eesnimi@osa.pri.ee> |
|---|---|
| Date | 2022-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]
| From | Bo Persson <bo@bo-persson.se> |
|---|---|
| Date | 2022-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]
| From | Ralf Goertz <me@myprovider.invalid> |
|---|---|
| Date | 2022-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]
| From | Manfred <noname@add.invalid> |
|---|---|
| Date | 2022-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]
| From | Christian Hanné <the.hanne@gmail.com> |
|---|---|
| Date | 2022-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