I'm using Visual Studio 2015.
Any idea why this code compiles:
#include <memory>
class Foo;
class Bar;
typedef std::pair<Foo*,std::weak_ptr<Bar>> Object;
typedef std::vector<Object> ObjectVect;
bool operator==( std::weak_ptr<Bar> left,
std::weak_ptr<Bar> right )
{
return left.lock() == right.lock();
}
int main( int argc, char* argv[] )
{
ObjectVect vect;
Object obj;
auto foundIter = std::find( vect.begin(), vect.end(), obj );
return 0;
}
while this one gives me error:
#include <memory>
class Foo;
namespace MyNamespace
{
class Bar;
}
typedef std::pair<Foo*,std::weak_ptr<MyNamespace::Bar>> Object;
typedef std::vector<Object> ObjectVect;
bool operator==( std::weak_ptr<MyNamespace::Bar> left,
std::weak_ptr<MyNamespace::Bar> right )
{
return left.lock() == right.lock();
}
int main( int argc, char* argv[] )
{
ObjectVect vect;
Object obj;
auto foundIter = std::find( vect.begin(), vect.end(), obj );
return 0;
}
Error C2678 binary '==': no operator found which takes a left-hand operand of type 'const std::weak_ptr' (or there is no acceptable conversion) test_cppunit_interpreter_base_multi_output c:\program files (x86)\microsoft visual studio 14.0\vc\include\utility 216
Looks like it failes to find the comparator when Bar
is located in a namespace...
Am I doing something wrong? Or could this be a compiler bug?
You should move operator==
into the namespace to make ADL take effect; ADL will also examine the types used as the template arguments (i.e. MyNamespace::Bar
) and add the associated namespaces (i.e MyNamespace
) to the set of name lookup.
i.e.
namespace MyNamespace
{
class Bar;
bool operator==( std::weak_ptr<Bar> left,
std::weak_ptr<Bar> right )
{
return left.lock() == right.lock();
}
}
Why the 1st case works fine?
Because ADL works for global namespace too. For the 1st case both Bar
and operator==
is defined in the same namespace (i.e. the global namespace).
Why the 2nd case doesn't work?
Firstly note that std::find
is defined in the namespace std
, and there're many operator==
s defined in it (with different parameter types). Then according to the rule of unqualified name lookup, when operator==
is found at the namespace std
, the name lookup stops. That means without the help of ADL, the operator==
defined in the global namespace won't be found at all.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With