免责声明:我精心设计了MCVE,以展示我在一个更大的项目中遇到的问题,该项目没有没有与天气有关。我选择了MCVE的名称和计划目标 only 以易于理解的方式演示问题。 我知道这种设计会影响现实生活中的预测计划。
我使用std::map
来存储结构,使用std::string
作为密钥。
struct Temps
{
//Temps(int l = 0, int h = 0)
Temps(int l, int h)
:low(l), high(h)
{}
int low;
int high;
};
int main()
{
std::map<std::string, Temps> forecast;
forecast.emplace("Monday", Temps(49, 40));
forecast.emplace("Tuesday", Temps(66, 35));
forecast.emplace("Wednesday", Temps(78, 40));
return 0;
}
但是,我遇到了问题。我可以使用迭代器访问地图中那些结构的内容,如预期的那样......
std::map<std::string, Temps>::iterator it;
it = forecast.find("Monday");
if(it != forecast.end())
{
std::cout << "Monday's high is " << it->second.high << "." << std::endl;
}
但是当我尝试使用地图上的[]
运算符进行访问时,我遇到了错误...
if(forecast.find("Tuesday") != forecast.end())
{
std::cout << "Tuesday's high is " << forecast["Tuesday"].high << std::endl;
}
我收到了一个巨大的,可怕的错误,总结为......
/ usr / include / c ++ / 5 / tuple | 1172 |错误:没有用于调用的匹配函数 “滕普斯::滕普斯()” |
我知道问题不在于结构或数据。发生了什么事?
答案 0 :(得分:1)
这在技术上可以被认为是Read the Documentation的一个案例,我为了解决这个问题而这样做。但是,解决方案可能并不完全明显。
struct Forecast
有一个构造函数,但它是需要两个参数的构造函数。这会导致与映射的[]
运算符的一个主要行为发生冲突,迭代器访问没有这个行为:
如果k与容器中任何元素的键不匹配,则该函数会使用该键插入一个新元素,并返回对其映射值的引用。请注意,即使没有为元素指定映射值(使用其默认构造函数构造元素),这也总是会将容器大小增加1。
由于Forecast
没有此类默认构造函数,因此map正在尝试调用不存在的函数。
如果我省略Forecast
上的构造函数,编译器会给结构一个默认的构造函数,一切都会好的。但是,由于我定义了一个构造函数,编译器不会这样做。
值得庆幸的是,解决方案非常简单:删除构造函数或添加默认构造函数。就我而言,我可以设置默认参数。
struct Temps
{
Temps(int l = 0, int h = 0)
:low(l), high(h)
{}
int low;
int high;
};
注意:有些人可能会争辩说上面的例子完全是愚蠢的 - 为什么不使用迭代器呢?在这种情况下,这将是一个非常好的主意。使用
[]
可能只是浪费时间,因为我正在搜索一个以防止错误。但是,是的情况,[]
是作业的最佳运算符,即使这不是一个。