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 (ie MyNamespace::Bar
) and add the associated namespaces (ie MyNamespace
) to the set of name lookup. ie
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 (ie 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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.