将结构添加到映射中
Adding a struct into a map
我在将结构添加到地图时遇到问题。我不太明白这个错误。
有 2 个错误:
- 我无法声明 'struct' 类型的地图
- 我无法使用插入 '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'
第一个问题是 map 需要一种方法来比较两个 myTypeDefStruct
。
您需要做的是为您的 class 定义 operator<
或 std::less
,或者将比较仿函数传递给地图。
std::map<T>::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;
}
已排序的映射需要一个 less 运算符 (operator<
) 来对元素进行排序。您必须提供这样的运算符,或者您必须设置排序功能。一种可能的解决方案是实施此运算符:
#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;
}
您的代码中存在几个问题:
- 该结构应该在函数 main 之外定义,在这种情况下看不出为什么要在那里定义它的原因,并且由于它在 main 内部是本地的,所以您不能在其他任何地方使用它!
- 您正在使用 C 风格
typedef struct ... StructName
而不是简单地使用 struct MyStruct
。
- 你的结构没有实现
operator<
,因此,因为 std::map
是一个 ordered 映射,它没有任何比较两个键(这里,键是你的结构),它不能插入任何对。
- 您的结构没有实现
operator==
,这对于实际 检索 某个键的值很重要。 .. 您应该能够检查密钥是否相似。
- 另一个小修复 - 使用
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;
}
我是如何确定第一个问题的?在第一个错误中(总是看第一个错误,其他的可能会误导!),是这样写的:
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')
我在将结构添加到地图时遇到问题。我不太明白这个错误。
有 2 个错误:
- 我无法声明 'struct' 类型的地图
- 我无法使用插入 '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'
第一个问题是 map 需要一种方法来比较两个 myTypeDefStruct
。
您需要做的是为您的 class 定义 operator<
或 std::less
,或者将比较仿函数传递给地图。
std::map<T>::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;
}
已排序的映射需要一个 less 运算符 (operator<
) 来对元素进行排序。您必须提供这样的运算符,或者您必须设置排序功能。一种可能的解决方案是实施此运算符:
#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;
}
您的代码中存在几个问题:
- 该结构应该在函数 main 之外定义,在这种情况下看不出为什么要在那里定义它的原因,并且由于它在 main 内部是本地的,所以您不能在其他任何地方使用它!
- 您正在使用 C 风格
typedef struct ... StructName
而不是简单地使用struct MyStruct
。 - 你的结构没有实现
operator<
,因此,因为std::map
是一个 ordered 映射,它没有任何比较两个键(这里,键是你的结构),它不能插入任何对。 - 您的结构没有实现
operator==
,这对于实际 检索 某个键的值很重要。 .. 您应该能够检查密钥是否相似。 - 另一个小修复 - 使用
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;
}
我是如何确定第一个问题的?在第一个错误中(总是看第一个错误,其他的可能会误导!),是这样写的:
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')