Problem with namespace lookup

D

drazse

I had a puzzling compiler error, which I was able to resolve after
some experimentation, but it still troubles me. I was able to isolate
the problem to a couple of lines.

Could someone explain what's wrong with the following code, please?

//=================================
#include <algorithm>

namespace NS {

struct C2
{
C2(int n) : value(n) {}
int value;
};

} // namespace NS

#ifndef WORKS
bool operator < (const NS::C2& s1, const NS::C2& s2)
{
return s1.value < s2.value;
}
#else
namespace NS {
bool operator < (const C2& s1, const C2& s2)
{
return s1.value < s2.value;
}
}
#endif

int main()
{
std::pair<int, NS::C2> p1(3, 7);
std::pair<int, NS::C2> p2(3, 8);
bool cmp1 = p1.second < p2.second; // OK
bool cmp2 = p1 < p2; // ERROR
return cmp2;
}
//=================================

Compiler output:

$ g++-4.3.2 paircmp.C
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4/bits/stl_pair.h:
In function ‘bool std::eek:perator<(const std::pair<_T1, _T2>&, const
std::pair<_T1, _T2>&) [with _T1 = int, _T2 = NS::C2]’:
paircmp.C:33: instantiated from here
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4/bits/stl_pair.h:
159: error: no match for ‘operator<’ in ‘__x->std::pair<int,
NS::C2>::second < __y->std::pair<int, NS::C2>::second’


BTW, if I compile it with -DWORKS, it compiles w/o any errors.
 
Z

ZikO

S

SG

I am not sure if I  understand it ...
If the operator is in global scope and its arguments are taken from NS
namespace, isn't p1 < p2 expression trying to find operator<() in NS
namespace according to how ADL works?

No. ADL considers "associated namespaces" only. If a funciton call's
parameter is an object of class NS::C2 then NS is part of the set of
associated namespaces. The global scope isn't. ADL kicks in after
scopes are searched from innermost to outermost. Since this search is
stopped after at least one name has been found some std::eek:perator<
declaration might hide your global operator<. But if you put your
operator in namespace NS then it will be added to the overload set
because of ADL.

This is explained well in Herb Sutter's article I linkes to.

Cheers!
SG
 
Z

ZikO

SG said:
No. ADL considers "associated namespaces" only. If a funciton call's
parameter is an object of class NS::C2 then NS is part of the set of
associated namespaces. The global scope isn't. ADL kicks in after
scopes are searched from innermost to outermost. Since this search is
stopped after at least one name has been found some std::eek:perator<
declaration might hide your global operator<. But if you put your
operator in namespace NS then it will be added to the overload set
because of ADL.

This is explained well in Herb Sutter's article I linkes to.

Cheers!
SG

I read it and understood it =). Thanks.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,997
Messages
2,570,240
Members
46,830
Latest member
HeleneMull

Latest Threads

Top