简体   繁体   English

为什么在我声明时“不匹配'operator<'”?

[英]Why “no match for 'operator<'” when I declared it?

It works for the struct xy that I declared.它适用于我声明的struct xy Why doesn't the same pattern work for complex<int> ?为什么相同的模式不适用于complex<int>

#include <complex>
#include <set>
using namespace std;

struct xy {
    int x, y;
};

bool operator< (const xy &a, const xy &b) {
    return a.x < b.x;
}

bool operator< (const complex<int> &a, const complex<int> &b) {
    return a.real() < b.real();
}

int main() {
    xy q;
    set<xy> s;
    s.insert(q);

    complex<int> p;
    set< complex<int> > t;   //If I comment out these two lines,
    t.insert(p);             //it compiles fine.

    return 0;
}

The error message:错误信息:

In file included from c:\m\lib\gcc\mingw32\4.8.1\include\c++\string:48:0,
                 from c:\m\lib\gcc\mingw32\4.8.1\include\c++\bits\locale_classes.h:40,
                 from c:\m\lib\gcc\mingw32\4.8.1\include\c++\bits\ios_base.h:41,
                 from c:\m\lib\gcc\mingw32\4.8.1\include\c++\ios:42,
                 from c:\m\lib\gcc\mingw32\4.8.1\include\c++\istream:38,
                 from c:\m\lib\gcc\mingw32\4.8.1\include\c++\sstream:38,
                 from c:\m\lib\gcc\mingw32\4.8.1\include\c++\complex:45,
                 from test.cpp:1:
c:\m\lib\gcc\mingw32\4.8.1\include\c++\bits\stl_function.h: In instantiation of 'bool less<>::operator()(const _Tp&, const _Tp&) const':
c:\m\lib\gcc\mingw32\4.8.1\include\c++\bits\stl_tree.h:1321:11:   required from 'pair<> _Rb_tree<>::_M_get_insert_unique_pos(const key_type&)'
c:\m\lib\gcc\mingw32\4.8.1\include\c++\bits\stl_tree.h:1374:47:   required from 'pair<> _Rb_tree<>::_M_insert_unique(_Arg&&)'
c:\m\lib\gcc\mingw32\4.8.1\include\c++\bits\stl_set.h:463:29:   required from 'pair<> __cxx1998::set<>::insert(const value_type&)'
c:\m\lib\gcc\mingw32\4.8.1\include\c++\debug\set.h:220:59:   required from 'pair<> __debug::set<>::insert(const value_type&)'
test.cpp:28:19:   required from here
c:\m\lib\gcc\mingw32\4.8.1\include\c++\bits\stl_function.h:235:20: 
error: no match for 'operator<' (operand types are 'const std::complex<int>' and 'const std::complex<int>')
       { return __x < __y; }

My best guess is that this has something to do with complex<T> being a class, not a struct.我最好的猜测是这与complex<T>是一个类而不是结构有关。 By I can't see the logic of why that should make a difference.我看不出为什么这应该有所作为的逻辑。 Or is it some template horribleness?或者它是某种模板的可怕之处?

What I see happening is that the STL at some point tries (roughly speaking) to do a < b , where a and b are complex<int> instances.我看到的情况是,STL 在某些时候尝试(粗略地说)做a < b ,其中abcomplex<int>实例。 So it's looking for bool operator< (const complex<int> &a, const complex<int> &b) .所以它正在寻找bool operator< (const complex<int> &a, const complex<int> &b) Well, there is exactly that declared just above main() .好吧,正好在main()之上声明了那个。 Why is it being unreasonable?为什么说不合理? I thought maybe it didn't like them being references.我想也许它不喜欢他们被引用。 But removing the ampersands made no difference to its complaint.但是删除&符号对其投诉没有任何影响。

It works for the struct xy that I declared.它适用于我声明的struct xy Why doesn't the same pattern work for complex<int> ?为什么相同的模式不适用于complex<int>

The reason is that when you use types from namespace std only, like std::set and std::complex , the compiler has no reason to look for operators in any other namespaces.原因是当您仅使用命名空间 std 中的类型时,如std::setstd::complex ,编译器没有理由在任何其他命名空间中查找运算符。

With struct xy this is different, as the operator is declared together with the type.struct xy不同,因为运算符是与类型一起声明的。


And also, the current standard says:而且,目前的标准说:

The effect of instantiating the template complex for any type other than float, double, or long double is unspecified.未指定为 float、double 或 long double 以外的任何类型实例化模板复合体的效果。

So using complex<int> might, or might not, work depending on which compiler you use.因此,根据您使用的编译器,使用complex<int>可能有效,也可能无效。 "Unspecified" is not as bad as "undefined", but of course not very reliable or portable. “未指定”没有“未定义”那么糟糕,但当然不是很可靠或便携。

One option is to write a custom comparison functor, and instantiate the set with this.一种选择是编写一个自定义比较函子,并用它实例化集合。

#include <complex>
#include <set>    

bool operator< (const std::complex<int> &a, const std::complex<int> &b) {
    return a.real() < b.real();
}

struct my_less {
    bool operator() (const std::complex<int>& lhs, const std::complex<int>& rhs) const{
        return lhs < rhs;
    }
};

int main() {
    std::complex<int> p;
    std::set< std::complex<int>, my_less > t;
    t.insert(p);

    return 0;
}

Sample on Coliru Coliru 样本

As of today, I am facing this issue with my Ubuntu's g++.截至今天,我的 Ubuntu 的 g++ 面临这个问题。 Suppose I have:假设我有:

namespace X { namespace Y { class C { ... }; } }

Now operator== is recognized if it's defined in a global namespace, such as:现在operator==是在全局命名空间中定义的,例如:

bool operator== (const X::Y::C& lhs, const X::Y::C& rhs) { return lhs == rhs; }

However, somehow compiler doesn't recognize operator< , if defined in the same way.但是,不知何故编译器无法识别operator< ,如果以相同方式定义。

Now following way works well:现在以下方法效果很好:

namespace X { namespace Y { 
     bool operator< (const C& lhs, const C& rhs) { return lhs < rhs; } } }

However, whether you should do it the same with expanding standard namespace std is a controversial topic.但是,是否应该对扩展标准namespace std也这样做是一个有争议的话题。 :-) :-)

暂无
暂无

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

相关问题 在h和cpp文件中声明的运算符*运算符不匹配 - no match for operator * operator declared in h and cpp file 当参数声明为const时,为什么不重载operator&gt;会起作用? - Why won't overloaded operator> work when the arguments are declared const? 为什么我收到“>>”运算符不匹配的错误? - Why I am getting error no match for ">>" operator? 为什么我收到“ operator ^”不匹配的错误 - Why do i get an error no match for 'operator^' 当在 class 中重载运算符 &lt;&lt; 时,为什么我必须将其声明为朋友 function,尽管它已经在 class 中声明? - When overloading operator << inside a class, why I must declare it as a friend function despite the fact that it is already declared inside the class? 错误:当我串流到cout时,与&#39;operator &lt;&#39;不匹配 - error: no match for ‘operator<’ when I stream to cout 为什么在不是“*this”的任何东西上使用基于范围的 for 循环时,我会得到“与 operator* 不匹配”? - Why am I getting a “no match for operator*” when using range-based for loop on anything that isn't “*this”? 为什么运算符&#39;=&#39;无法匹配? - why operator '=' can not match? 为什么搜索迭代器时会出现“error: no match for 'operator&lt;&lt;'”? - Why does " error: no match for 'operator<<' " occur when searching for the iterator? 为什么在使用 `std::find` 时错误与“operator==”不匹配? - Why the error no match for 'operator==', when using `std::find`?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM