如何使用复数作为地图中的键?这是一个不能编译的小例子:
#include <complex>
#include <map>
int main() {
std::complex<double> zero = 0.0;
std::map<std::complex<double>, int> theMap;
return (theMap.count(zero));
}
我可以创建没有错误的地图,但可以创建任何方法(例如,上面的count
调用以及find
,[]
运算符,insert
等。 )生成编译时错误。这绝对是我理解的问题,因为我使用clang和g ++得到了类似的结果。
看起来编译器无法比较两个复数。我创建了所有的比较运算符(例如bool operator< (const std::complex & lhs, const std::complex & rhs) {return (std::norm(lhs) < std::norm(rhs));}
),它用于比较复数(只要你不介意3 < -5
为真,这应该适用于map
),但编译器没有拿起它。
我对unordered_map有类似的问题(complex<double>
没有哈希)
答案 0 :(得分:1)
我没有看过实现,但是每个cppreference std::map
使用std::less<T>
作为比较运算符,可能不适用于std::complex
,如果你实现一个传递它作为第三个模板std::map<std::complex, int, LessOperator>
中的参数与std:unordered_map
类似,您可以在其中提供哈希函子和平等函子。如果这两个都已实现,您可以使用std::complex
作为密钥。
答案 1 :(得分:1)
上述评论已指出主要答案。问题是复数不是有序的,因此std::complex<T>
没有预先定义的小运算符。不过,您可以自己定义一个,通过使用std::array<T,2>
已经定义的较小运算符可以轻松实现:
#include <iostream>
#include<complex>
#include<map>
#include<unordered_map>
#include<array>
template<typename T> struct less {};
template<typename T>
struct less<std::complex<T> >
{
bool operator()(std::complex<T> const& a, std::complex<T> const& b)
{
return std::array<T,2>{a.real(),a.imag()} < std::array<T,2>{b.real(),b.imag()};
}
};
int main()
{
std::map<std::complex<double>, int, less<std::complex<double> > > m;
m[std::complex<double>(1.0,0.0)]=1;
m[std::complex<double>(0.0,1.0)]=2;
m[{0.5,0.5}]=3;
return 0;
}
查看实时示例here。
答案 2 :(得分:1)
您的方法存在的问题是,对于有序容器,例如std::map
,密钥必须符合严格弱排序。来自wikipedia:
严格的弱排序具有以下属性。对于S中的所有x和y,
对于所有x,不是x&lt; x(反射性)。
对于所有x,y,如果x&lt;那么y&lt; x(不对称)。
对于所有x,y和z,如果x&lt; y和y&lt; z然后x&lt; z(及物性)。
对于所有x,y和z,如果x与y无法比较,并且y与z无法比较,则x与z无法比较(无法比较的传递性)。
不幸的是,没有自然的方法对复数强加严格的弱序。例如,是1&lt; i 或 i &lt; 1?如果你说 - 我≮1和1≮我,那么通过规则严格的弱排序它必须是真实的 - i ≮ I 的。这确实意味着。
您需要使用复数作为键,您不太可能需要和订购容器。尝试查看std::unordered_map
。
来自C ++ 11标准的第23.2.4.2节[associative.reqmts]:
每个关联容器都在Key上进行参数化和一个排序关系比较,它对Key的元素产生严格的弱排序(25.4)。此外,map和multimap将任意类型T与Key相关联。 Compare类型的对象称为容器的比较对象。