std::map 包含最后一个实例的值,然后才被告知存储该值
std::map contains value from last instance before it's told to store said value
所以最近我在试验一些代码时发现了一个非常奇怪的错误。我创建了一个 std::map 来为我的程序存储字体。然而,通过长时间的调试,我设法发现在我将 "arial" 放入其中之前,该映射存储了一个带有键 "arial" 的值 (NULL)。所以我还发现,当我更改程序使其永远不会在地图中放置 "arial" 时,地图仍然包含 "arial".
这是我设置的 class 层次结构的基本再现:
#include "SDL_ttf.h"
#include <map>
#include <string>
#include <array>
class AssetManager{
public:
void addFont(std::string ID, std::string path, int fontSize){
std::cout <<""; //if we put a breakpoint here, the first time it stops, "arial" is already defined within fonts.
fonts.emplace(ID, TTF_OpenFont(path, fontSize);
}
private:
std::map<std::string, TTF_Font*> fonts;
};
class Game{
public:
void init(){
if(TTF_Init() == -1){
std::cout << "Failed to init SDL_TTF" << std::endl; //this has never gotten called; TTF always succeeds in initializing
}
assets->addFont("fontname", "assets/Arial.ttf", 16);
}
static shared_ptr<AssetManager>(new AssetManager) assets;
};
main(int argc, char* argv[]){
Game *game = nullptr;
game = new Game;
game->init();
}
如您所见,在该程序中,我们从未添加名为 "arial" 的字体,但出于某种原因(我假设是缓存错误),字体包含数据对于 "arial" 之前,在程序的这个实例中,"arial" 是什么。换句话说,"arial" 是在前一个实例中定义的,但从未在这个实例中定义过,但是映射仍然有一个键 "arial"。如果有人知道为什么或如何发生这样的事情,我很想听听。
我猜你正在使用 std::map
s operator[]
。
该操作员不仅会查找现有条目。它将 创建 如果条目不存在,则使用默认构造(实际上 "value initialized")值。
这其实在很多情况下都是一个特性。例如,它允许您执行类似以下操作来计算字符串中字符的出现次数:
std::map<char, int> result;
for (const auto& c : some_string) {
++result[c];
}
如果您只想查找一个键,没有插入行为,那么您有几个选择:
和others.
所以最近我在试验一些代码时发现了一个非常奇怪的错误。我创建了一个 std::map 来为我的程序存储字体。然而,通过长时间的调试,我设法发现在我将 "arial" 放入其中之前,该映射存储了一个带有键 "arial" 的值 (NULL)。所以我还发现,当我更改程序使其永远不会在地图中放置 "arial" 时,地图仍然包含 "arial".
这是我设置的 class 层次结构的基本再现:
#include "SDL_ttf.h"
#include <map>
#include <string>
#include <array>
class AssetManager{
public:
void addFont(std::string ID, std::string path, int fontSize){
std::cout <<""; //if we put a breakpoint here, the first time it stops, "arial" is already defined within fonts.
fonts.emplace(ID, TTF_OpenFont(path, fontSize);
}
private:
std::map<std::string, TTF_Font*> fonts;
};
class Game{
public:
void init(){
if(TTF_Init() == -1){
std::cout << "Failed to init SDL_TTF" << std::endl; //this has never gotten called; TTF always succeeds in initializing
}
assets->addFont("fontname", "assets/Arial.ttf", 16);
}
static shared_ptr<AssetManager>(new AssetManager) assets;
};
main(int argc, char* argv[]){
Game *game = nullptr;
game = new Game;
game->init();
}
如您所见,在该程序中,我们从未添加名为 "arial" 的字体,但出于某种原因(我假设是缓存错误),字体包含数据对于 "arial" 之前,在程序的这个实例中,"arial" 是什么。换句话说,"arial" 是在前一个实例中定义的,但从未在这个实例中定义过,但是映射仍然有一个键 "arial"。如果有人知道为什么或如何发生这样的事情,我很想听听。
我猜你正在使用 std::map
s operator[]
。
该操作员不仅会查找现有条目。它将 创建 如果条目不存在,则使用默认构造(实际上 "value initialized")值。
这其实在很多情况下都是一个特性。例如,它允许您执行类似以下操作来计算字符串中字符的出现次数:
std::map<char, int> result;
for (const auto& c : some_string) {
++result[c];
}
如果您只想查找一个键,没有插入行为,那么您有几个选择:
和others.