繁体   English   中英

为什么在命名空间中定义的类型实例化的std :: weak_ptr重载operator ==无法找到?

[英]Why overloaded operator== for std::weak_ptr instantiated with type defined in namespace can't be found?

我正在使用Visual Studio 2015。

知道为什么这个代码编译:

#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;
}

虽然这个给了我错误:

#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;
}

错误C2678二进制'==':找不到运算符,它接受类型'const std :: weak_ptr'的左手操作数(或者没有可接受的转换)test_cppunit_interpreter_base_multi_output c:\\ program files(x86)\\ microsoft visual studio 14.0 \\ vc \\ include \\ utility 216

Bar位于命名空间中时,看起来很难找到比较器...

难道我做错了什么? 或者这可能是编译器错误?

您应该将operator==移动到命名空间中以使ADL生效; ADL还将检查用作模板参数的类型(即MyNamespace::Bar ),并将关联的命名空间(即MyNamespace )添加到名称查找集中。

namespace MyNamespace
{
    class Bar;
    bool operator==( std::weak_ptr<Bar> left,
                     std::weak_ptr<Bar> right )
    {
        return left.lock() == right.lock();
    }

}

为什么第一种情况正常?

因为ADL也适用于全局命名空间。 对于第一种情况, Baroperator==都在同一名称空间(即全局名称空间)中定义。

为什么第二种情况不起作用?

首先请注意, std::find是在命名空间std定义的,并且在其中定义了许多operator== (具有不同的参数类型)。 然后根据非限定名称查找规则,当在命名空间std找到operator==时,名称查找停止。 这意味着没有ADL的帮助,根本就找不到全局命名空间中定义的operator==

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM