C ++ bool std :: operator&lt;带有键的映射错误std :: unordered_set <int,std :: hash <int>&gt; </int,std :: hash <int>

时间:2014-06-16 22:54:34

标签: c++ unordered-set

当我尝试在此地图中插入时:

std::map<std::unordered_set<int >, std::pair<float, std::pair<float, float >> >

我收到此错误

  

错误C2784:&#39; bool std :: operator&lt;(const std :: _ Tree&lt; _Traits&gt;&amp;,const   的std :: _树&LT; _Traits&GT; &安培;)&#39; :无法推断模板参数   &#39; const std :: _ Tree&lt; _Traits&gt; &安培;&#39;来自&#39; const   的std :: unordered_set,性病:: equal_to&LT; _Kty&GT;,的std ::分配器&LT; _Kty&GT;&GT;&#39;

我的数据定义如下:

    struct Trans {
    int Item;
    float Prob;
    float W;
};
bool operator<(const Trans &a, const Trans &b)
    {
        return a.Item < b.Item;
    }
    bool operator==( Trans c,  Trans d) { return c.Item == d.Item; }


    struct MyHash {
        size_t operator()(const Trans& x) const { return std::hash<int>()(x.Item);  }
    };


std::vector<std::vector<Trans>> data;
std::map<std::unordered_set<int>, float> S1;
std::map<std::unordered_set<int >, std::pair<float, std::pair<float, float >> > S2;
std::map<std::unordered_set<int >, std::pair<float, std::pair<float, float >> > S3;

有问题的部分:

    do
        {

std::unordered_set<Trans, MyHash> KS(data[i].begin(), data[i].begin() + k);
std::unordered_set<int > elem;

float esupp = 1;
float Weight = 0;
float Wesupp = 1;
    for (auto const &iter : KS)
        {
          elem.insert(iter.Item);
           esupp *= iter.Prob;
          Weight += iter.W;
        }
        Weight = Weight / k;


        /*
        some code, and until here I didn't get any problem
        */

            **// This the area that has the problem** 

    S1[elem] = std::move(S1[elem] + esupp);
    Wesupp = Weight * S1[elem];
    S2[elem].first = std::move(S2[elem].first + esupp);
    S2[elem].second = std::make_pair(elem, Wesupp);
  } while (next_combination(data[i].begin(), data[i].begin() + k, data[i].end()));

2 个答案:

答案 0 :(得分:1)

除非提供了比较器,否则std::map期望其密钥实现运算符<

您的密钥类型std::unordered_set未实施&#34;小于&#34;。

As @ T.C。提及,您可以使用std::set代替std::unordered_set

答案 1 :(得分:1)

正如Drew Dormann指出的那样,您当前的错误是std::unordered_set缺少operator <造成的。

但是,

std::set确实有一个重载的operator <,所以你可以使用它。

但是,代码的问题比这更深入。例如:

S1[elem] = std::move(S1[elem] + esupp);

您正在分配float。使用std::move绝对没有意义,特别是因为S1[elem] + esupp已经是右值。编写此行的常用方法是S1[elem] += esupp;

S2[elem].first = std::move(S2[elem].first + esupp);

同样的问题。

S2[elem].second = std::make_pair(elem, Wesupp);

作业的LHS是std::pair<float, float>; RHS创建std::pair<std::unordered_set<int>, float>

正如我在评论中提到的,std::pair<float, std::pair<float, float>>只是糟糕的设计。它应至少为std::tuple或甚至更好的std::array<float, 3>或甚至更好的简单结构,以明确三个浮点数中的每一个实际意味着什么。

此外,使用set<int>(无序或无序)作为地图中的键是一个相当奇怪的设计。您是否只想维护一个可以迭代的set<int> - 3x float配对列表,或者您是否真的希望能够使用set<int>进行有效索引?如果您不需要有效的索引,只需使用对向量而不是映射。