[英]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
,其中a
和b
是complex<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 forcomplex<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::set
和std::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;
}
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.