在std :: map中无法访问struct值 [英] Cannot access struct value in std::map

查看:134
本文介绍了在std :: map中无法访问struct值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


免责声明:我制作了MCVE,展示了一个与天气无关的更大项目的问题。我选择了MCVE的名称和计划目标以容易理解的方式证明问题。

DISCLAIMER: I crafted the MCVE to demonstrate an issue I had with a much larger project that has nothing to do with the weather. I chose the MCVE's names and program goal only to demonstrate the problem in an easy-to-understand way. I know this design would suck for a real-life forecast program.

我正在使用 std :: map 存储结构体,使用 std :: string 作为键。

I am using a std::map to store structs, using std::string as a key.

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;
}

但是,我有一个问题。我可以使用迭代器访问地图中的这些结构的内容,如预期的那样...

However, I'm having a problem. I can access the contents of those structs within the map using iterators, as expected...

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;
}

但是当我尝试使用 [] 操作符在地图上,我遇到错误...

But when I try to access using the [] operator on the map, I run into an error...

if(forecast.find("Tuesday") != forecast.end())
{
    std::cout << "Tuesday's high is " << forecast["Tuesday"].high << std::endl;
}

我收到一个巨大的,可怕的错误,总结到...

I get a massive, hideous error, which summarizes down to...


/ usr / include / c ++ / 5 / tuple | 1172 |错误:调用
的匹配函数Temps :: Temps()'|

/usr/include/c++/5/tuple|1172|error: no matching function for call to ‘Temps::Temps()’|

我知道问题既不是结构体也不是数据。

I know the problem is neither with the struct or the data. What's going on?

推荐答案

这在技术上可以被认为是一种 阅读文档 ,为了自己解决这个问题。但是,解决方案可能并不是完全明显的。

This technically could be considered a case of Read the Documentation, which I did in order to solve this for myself. However, the solution might not be entirely obvious right off the bat.

结构预测有一个构造函数,但是它是一个构造函数,需要两个参数。这导致与地图的 [] 运算符的一个主要行为发生冲突,迭代器访问没有:

The struct Forecast has a constructor, but it is a constructor that requires two arguments. This causes a conflict with one major behavior of the map's [] operator, which the iterator access does not have:


如果k与容器中任何元素的键不匹配,该函数将使用该键插入一个新元素,并返回其映射值的引用。请注意,这总是将容器大小增加1,即使没有为元素分配映射值(元素使用其默认构造函数构造)。

If k does not match the key of any element in the container, the function inserts a new element with that key and returns a reference to its mapped value. Notice that this always increases the container size by one, even if no mapped value is assigned to the element (the element is constructed using its default constructor).

因为预测没有这样的默认构造函数,所以map正在尝试调用一个不存在的函数。

Because Forecast has no such default constructor, map is attempting to call a function which does not exist.

如果我省略了 Forecast 上的构造函数,编译器将给予一个默认构造函数,好好但是,由于我定义了一个构造函数,编译器不会这样做。

Had I omitted the constructor on Forecast, the compiler would have given the struct a default constructor, and all would be well. However, since I defined a constructor, the compiler won't do that.

幸运的是,解决方案非常简单:删除构造函数添加默认构造函数。在我的情况下,我可以设置默认参数。

Thankfully, the solution is quite simple: either remove the constructor or add a default constructor. In my case, I can just set default arguments.

struct Temps
{
    Temps(int l = 0, int h = 0)
        :low(l), high(h)
        {}
    int low;
    int high;
};








注意:有些人可能认为上面的例子完全是愚蠢的 - 为什么不使用迭代器?在这种情况下,这将是一个很好的主意。使用 [] 可能只是浪费时间,因为我正在搜索一个以防止错误。但是, $ b

NOTE: Some may argue that the above example is entirely silly - why not just use the iterator? In this case, that would be a very good idea. Using the [] is probably just wasting time, since I'm searching for one anyway to prevent errors. However, there are cases where [] is the best operator for the job, even if this isn't one.

这篇关于在std :: map中无法访问struct值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆