【问题标题】:Adding a struct into a map将结构添加到地图中
【发布时间】:2020-10-25 08:19:39
【问题描述】:

我在将结构添加到地图时遇到问题。我真的不明白这个错误。

有2个错误:

  1. 我无法声明具有“结构”类型的地图
  2. 我无法使用 insert 将我的结构“插入”到地图中

我做错了什么?

#include <iostream>
#include <map>

int main()
{

    typedef struct 
    {   
        std::string stringVar;
        unsigned unsignedVar;
        float floatVar;
    } MyTypeDefStruct;

    MyTypeDefStruct myTypeDefStruct;
    myTypeDefStruct.stringVar = "myStr";
    myTypeDefStruct.unsignedVar = 1000;
    myTypeDefStruct.floatVar = -10.0;

    float anotherFloat = -20.0;

    std::map<MyTypeDefStruct, float> myMap;

    myMap.insert(std::pair<MyTypeDefStruct, float> (myTypeDefStruct, anotherFloat));                                                                                                                                                                                                      

    return 0;
}

错误:

test.cpp: In function 'int main()':
test.cpp:21:36: error: template argument for 'template<class _Tp> struct std::less' uses local type 'main()::MyTypeDefStruct'
 std::map<MyTypeDefStruct, float> myMap;
                                ^
test.cpp:21:36: error:   trying to instantiate 'template<class _Tp> struct std::less'
test.cpp:21:36: error: template argument 3 is invalid
test.cpp:21:36: error: template argument for 'template<class _T1, class _T2> struct std::pair' uses local type 'const main()::MyTypeDefStruct'
test.cpp:21:36: error:   trying to instantiate 'template<class _T1, class _T2> struct std::pair'
test.cpp:21:36: error: template argument 4 is invalid
test.cpp:21:43: error: invalid type in declaration before ';' token
 std::map<MyTypeDefStruct, float> myMap;
                                       ^
test.cpp:23:11: error: request for member 'insert' in 'myMap', which is of non-class type 'int'
 myMap.insert(std::pair<MyTypeDefStruct, float> (myTypeDefStruct, anotherFloat));
       ^
test.cpp:23:50: error: template argument for 'template<class _T1, class _T2> struct std::pair' uses local type 'main()::MyTypeDefStruct'
 myMap.insert(std::pair<MyTypeDefStruct, float> (myTypeDefStruct, anotherFloat));
                                              ^
test.cpp:23:50: error:   trying to instantiate 'template<class _T1, class _T2> struct std::pair'

【问题讨论】:

  • 排序后的地图需要一个 less 运算符 (operator&lt;) 来对元素进行排序。您必须提供这样的运算符,否则您必须设置排序功能。
  • @ThomasSablik 你可以把你的答案放到下面的答案部分。

标签: c++ dictionary stl stdmap


【解决方案1】:

您的代码中有几个问题:

  1. 该结构应该在函数 main 之外定义,在这种情况下看不出为什么要在那里定义它的原因,而且由于它是 main 内部的本地结构,所以不能在其他任何地方使用它!李>
  2. 您使用的是 C 风格的 typedef struct ... StructName,而不是简单地使用 struct MyStruct
  3. 您的结构没有实现operator&lt;,因此,因为std::map 是一个有序 映射,并且它不需要比较两个键(这里,键是您的struct),它不能插入任何对。
  4. 您的结构没有实现operator==,这对于实际检索某个键的值很重要...您应该能够检查键是相似的。
  5. 另一个小修复 - 使用 std::make_pair 而不是它的 ctor。

您的代码应如下所示:

#include <iostream>
#include <map>

struct MyStruct
{   
    std::string stringVar;
    unsigned unsignedVar;
    float floatVar;

    friend bool operator<(const MyStruct& l, const MyStruct& r)
    {
        return std::tie(l.stringVar, l.unsignedVar, l.floatVar)
             < std::tie(r.stringVar, r.unsignedVar, r.floatVar);
    }

    friend bool operator==(const MyStruct& l, const MyStruct& r)
    {
        return std::tie(l.stringVar, l.unsignedVar, l.floatVar)
             == std::tie(r.stringVar, r.unsignedVar, r.floatVar);
    }
};  

int main()
{
    MyStruct my_struct;
    my_struct.stringVar = "myStr";
    my_struct.unsignedVar = 1000;
    my_struct.floatVar = -10.0;

    float anotherFloat = -20.0;

    std::map<MyStruct, float> myMap;

    myMap.insert(std::make_pair(my_struct, anotherFloat));

    return 0;
}

我是如何确定第一个问题的?在第一个错误(总是看first错误,其他的可能会误导!),它是这样写的:

test.cpp:21:36: error: template argument for 'template<class _Tp> struct std::less' uses local type 'main()::MyTypeDefStruct'
 std::map<MyTypeDefStruct, float> myMap;

注意这里的模板初始化使用的是main()::MyTypeDefStruct而不是MyTypeDefStruct!!!这些类型不同,第一种仅在main()!

范围中可用

第三点是因为当你修正第一点时,你会得到:

error: no match for 'operator<' (operand types are 'const MyStruct' and 'const MyStruct')

【讨论】:

  • 感谢所有提示! c++98 有 std::tie 替代方案吗?
  • @wait_wut 为什么在 2020 年使用 C++98?
  • @bolov 不幸的是,这是一个项目限制。
  • @wait_wut 只是写下l.stringVar &lt; r.stringVar || ...。你可以自己想办法! std::tie 更简单,不是必须的!
  • @wait_wut 另外,如果它解决了您的问题,您应该接受答案
【解决方案2】:

第一个问题是 map 需要一种比较两个myTypeDefStructs 的方法。 您需要为您的班级定义 operator&lt;std::less,或将比较函子传递给地图。

【讨论】:

    【解决方案3】:

    std::map&lt;T&gt;::insert 使用比较器插入您的元素,但没有为您的结构定义,因此尝试使用类似以下的内容

    #include <iostream>
    #include <map>
    struct MyTypeDefStruct
    {
        std::string stringVar;
        unsigned unsignedVar;
        float floatVar;
    } ;
    
    bool operator<(const MyTypeDefStruct& lhs, const MyTypeDefStruct& rhs){
        return lhs.unsignedVar < rhs.unsignedVar;
    }
    
    int main()
    {
    
    
        MyTypeDefStruct myTypeDefStruct;
        myTypeDefStruct.stringVar = "myStr";
        myTypeDefStruct.unsignedVar = 1000;
        myTypeDefStruct.floatVar = -10.0;
    
        float anotherFloat = -20.0;
    
        std::map<MyTypeDefStruct, float> myMap;
    
        myMap.insert(std::pair<MyTypeDefStruct, float> (myTypeDefStruct, anotherFloat));
    
        return 0;
    }
    

    【讨论】:

      【解决方案4】:

      排序后的映射需要一个 less 运算符 (operator&lt;) 来对元素进行排序。您必须提供这样的运算符,或者您必须设置排序功能。一种可能的解决方案是实现此运算符:

      #include <iostream>
      #include <map>
      
      
      struct MyTypeDefStruct {   
          std::string stringVar;
          unsigned unsignedVar;
          float floatVar;
      };
      
      bool operator<(const MyTypeDefStruct &lhs, const MyTypeDefStruct &rhs) {
          if (lhs.stringVar < rhs.stringVar) return true;
          if (lhs.stringVar > rhs.stringVar) return false;
          if (lhs.unsignedVar < rhs.unsignedVar) return true;
          if (lhs.unsignedVar > rhs.unsignedVar) return false;
          if (lhs.floatVar < rhs.floatVar) return true;
          return false;
      }
      
      int main() {
      
          MyTypeDefStruct myTypeDefStruct;
          myTypeDefStruct.stringVar = "myStr";
          myTypeDefStruct.unsignedVar = 1000;
          myTypeDefStruct.floatVar = -10.0;
      
          float anotherFloat = -20.0;
      
          std::map<MyTypeDefStruct, float> myMap;
      
          myMap.insert(std::pair<MyTypeDefStruct, float> (myTypeDefStruct, anotherFloat));                                                                                                                                                                                                      
      
          return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-01
        • 1970-01-01
        • 2021-12-24
        • 2021-09-05
        • 2015-04-11
        相关资源
        最近更新 更多