使用std :: complex <double>作为std :: map键</double>

时间:2014-10-07 20:58:32

标签: c++ c++11 stdmap

如何使用复数作为地图中的键?这是一个不能编译的小例子:

#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>没有哈希)

3 个答案:

答案 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类型的对象称为容器的比较对象。