std :: vector< T>的比较运算符找不到T的比较运算符 [英] Comparison operator for std::vector<T> fails to find comparison operator for T

查看:106
本文介绍了std :: vector< T>的比较运算符找不到T的比较运算符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下非常简单的代码无法编译

The following very simple code won't compile

#include <vector>
#include <string>


namespace Foobar {
    struct Test {
        std::string f;
        std::uint16_t uuid;
    };
}

bool operator==(const Foobar::Test& lhs, const Foobar::Test& rhs){
    return lhs.f == rhs.f && lhs.uuid == rhs.uuid;
}


int main(){

    std::vector<Foobar::Test> a;
    std::vector<Foobar::Test> b;

    if(a==b){

    }

    return 0;
}

https://godbolt.org/g/zn6UgJ

不会在我拥有的任何编译器中进行编译。

Won't compile in any of the compilers I have.

以下内容

#include <vector>
#include <string>


namespace Foobar {
    struct Test {
        std::string f;
        std::uint16_t uuid;
    };

    bool operator==(const Foobar::Test& lhs, const Foobar::Test& rhs){
        return lhs.f == rhs.f && lhs.uuid == rhs.uuid;
    }
}



int main(){

    std::vector<Foobar::Test> a;
    std::vector<Foobar::Test> b;

    if(a==b){

    }

    return 0;
}

https://godbolt.org/g/o4pc1b

编译起来还不错,这让我觉得 std :: vector< T> 比较运算符在 T 的命名空间中查找,为什么不考虑全局命名空间?

Compiles just fine, which makes me think std::vector<T> comparison operator looks in the namespace of T, why won't it consider the global namespace?

推荐答案

普通的非限定名称查找在使用该名称的上下文中开始查找,并向上走动包含作用域的链。它在包含匹配名称的最嵌套的范围内停止。即使后来发现如此找到的名称不合适(例如,函数重载对于给定的调用而言是不可行的;或者成员函数不可访问),这也是正确的。

Ordinary unqualified name lookup starts looking in the context where the name is used, and walks up the chain of enclosing scopes. It stops in the most nested scope that contains the matching name. This is true even if the name thus found is later determined to be unsuitable (e.g. the function overload is non-viable for a given call; or the member function is inaccessible).

这里,查找的上下文是 std :: operator ==(vector,vector),因此它开始在命名空间 std 。 operator == 在名称空间 std 中有很多重载,因此普通查找在此停止并且永远不会到达全局

Here, the context of the lookup is std::operator==(vector, vector), so it starts looking in namespace std. There are plenty of overloads of operator== in namespace std, so the ordinary lookup stops there and never reaches the global namespace.

在第二个示例中,重载是通过依赖于参数的查找来发现的。除了非限定性查找之外,此查找还专门针对函数调用中的函数名称执行,并且在与调用参数类型相关联的范围内查找名称。在示例中,名称空间 Foobar Foobar :: Test 关联,因此依赖于参数的查找搜索该名称空间和找到 Foobar :: operator ==

In the second example, the overload is found by argument-dependent lookup. This lookup is performed specifically for function names in function calls, in addition to unqualified lookup, and looks for names in scopes associated with the types of the call's arguments. In the example, namespace Foobar is associated with Foobar::Test, and so argument-dependent lookup searches that namespace and finds Foobar::operator==.

因此,逻辑上属于该类的自由函数'公共接口-例如重载的运算符-通常应在与类本身相同的名称空间中定义,以便为依赖于参数的查找提供工作机会。 std :: operator ==(vector,vector)是一个很好的例子- a == b 该示例通过依赖于参数的查找进行工作。

For this reason, free functions that are logically part of the class' public interface - e.g. overloaded operators - should generally be defined in the same namespace as the class itself, to give argument-dependent lookup a chance to work. std::operator==(vector, vector) is a good example of that - a==b in your example works by way of argument-dependent lookup.

这篇关于std :: vector&lt; T&gt;的比较运算符找不到T的比较运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆