了解如何使用 SFML 函数将数据添加到地图
Understanding how to add data to a map with SFML functions
我正在用 SFML 和 c++ 11 做这个简单的教程。我正处于他教授地图容器的位置。我有 c# 知识,我的理解是地图与字典相同。我的问题是关于他提供但没有很好解释的代码片段。
TextureHolder.h
std::map<std::string, sf::Texture> m_textures;
TextureHolder.cpp
sf::Texture& TextureHolder::GetTexture(std::string const& filename)
{
auto& r_textures = m_s_instance -> m_textures;
auto keyValuePair = r_textures.find(filename);
if (keyValuePair != r_textures.end())
{
return keyValuePair->second;
}
else
{
auto& texture = r_textures[filename];
texture.loadFromFile(filename);
return texture;
}
}
除了 else 语句,我什么都懂。这是我对发生的事情的理解,但如果有人能向我澄清实际发生的事情以及我为什么错了,我将不胜感激。
auto& texture = r_textures[filename]
这将创建一个新的键值对,键为文件名。然后它将值分配给纹理,这是一个空值,因为没有加载纹理。
texture.loadFromFile(filename);
这将加载一个纹理文件并将其分配给纹理。这是我完全迷路的地方。这条线也以某种方式将纹理添加到键的值中。
然后它returns调用函数的纹理。
这可能更多是对SFML如何处理纹理对象的误解,但我仍然对这条线如何与地图中的键值对通信感到困惑。
auto& texture = r_textures[filename]
This creates a new key value pair with the key of filename. It then assigns the value to texture, which is an empty value since no texture has been loaded.
它不会将 值 分配给 texture
。它使 texture
成为对新创建的纹理的引用。这就是 auto&
中的 &
所做的。
texture.loadFromFile(filename);
This loads a texture file and assigns it to texture. This is where i'm completely lost. Some way this line is also adding the texture to the value of the key.
它没有将它分配给 texture
,而是将它分配给 texture
引用的对象——记住,texture
是一个引用。指贴图中的贴图。
Then it returns the texture to the calling function.
实际上,它 return 是对它的引用。请记住,return 类型是 sf::Texture&
.
auto& texture = r_textures[filename] This creates a new key value pair
with the key of filename. It then assigns the value to texture, which
is an empty value since no texture has been loaded.
不完全正确。 texture
是参考。它本身并不是一个谨慎的对象。
这将创建一个新的 key/value 对,并在映射中设置引用 texture
以引用新创建的值。
随后的 loadFromFile()
通过 texture
引用调用 loadFromFile()
方法。这恰好指的是地图中新插入的值。
然后,返回对从文件中新加载的值的引用。
胶囊摘要:它搜索地图以查看是否找到键,如果找到了 returns 对键值的引用。否则它会为那个键创建一个新的 key/value 对,初始化新值,然后 returns 它。
在此声明中
auto& texture = r_textures[filename];
在映射中创建了一个新对,键等于 filename
,映射值等于通过调用默认构造函数创建的对象 sf::Texture()
。运算符 returns 是对创建的映射值的引用。此引用存储在变量 texture
中,该变量又是一个引用。所以这个引用指的是映射类型的原始默认创建对象。
然后更新存储在映射中的映射类型的原始对象
texture.loadFromFile(filename);
因为变量texture
是对象的引用。
最后这个引用是映射中原始映射对象的引用从函数返回
return texture;
因此 operator []
returns 映射对象的引用(如果对应于指定键的对象已经存在于映射中)或者创建一个新的映射对象调用其默认构造函数并且还 returns 对新创建的映射对象的引用。
其他答案解释了您发布的代码。
然而,正如我的评论所建议的,使用 std::map::insert() 而不是 find()
然后 []
可能会使代码更清晰。诀窍是知道 std::map::insert
return 是什么以及如何使用它。
sf::Texture& TextureHolder::GetTexture(std::string const& filename)
{
auto& r_textures = m_s_instance -> m_textures;
// potentially insert a new texture. If not inserted, then the
// current one remains in the map
auto ret = r_textures.insert(std::make_pair(filename, sf::Texture()));
// ret is a std::pair<map::iterator, bool>, where map::iterator is
// the iterator to the existing or newly inserted item. The second
// is a bool that is either true or false, depending on whether new item
// was inserted or not.
// Now get the texture. A map's iterator is itself a pair, so
// 'first' of this pair is the filename, and 'second' is the texture.
auto& texture = ret.first->second;
// this tells us if it's a new item inserted
if ( ret.second )
texture.loadFromFile(filename);
return texture;
}
这基本上与您的版本做同样的事情,只是它使用 map::insert
来确定是否已插入新项目,并使用 insert
的 return 值继续前进.
请注意,map::insert
需要一个 std::pair
,它由 "potential" 新键和值组成(它是 "potential",因为我们不知道是否有新的是否插入密钥——我们让 insert() 决定)。
如果密钥已经存在,那么 insert
除了 return iterator/bool 对之外什么都不做。如果密钥不存在,则 insert
插入一个全新的 sf::Texture
默认构造一个(参见 make_pair
的第二个参数),然后是 iterator/bool 对是 returned.
我正在用 SFML 和 c++ 11 做这个简单的教程。我正处于他教授地图容器的位置。我有 c# 知识,我的理解是地图与字典相同。我的问题是关于他提供但没有很好解释的代码片段。
TextureHolder.h
std::map<std::string, sf::Texture> m_textures;
TextureHolder.cpp
sf::Texture& TextureHolder::GetTexture(std::string const& filename)
{
auto& r_textures = m_s_instance -> m_textures;
auto keyValuePair = r_textures.find(filename);
if (keyValuePair != r_textures.end())
{
return keyValuePair->second;
}
else
{
auto& texture = r_textures[filename];
texture.loadFromFile(filename);
return texture;
}
}
除了 else 语句,我什么都懂。这是我对发生的事情的理解,但如果有人能向我澄清实际发生的事情以及我为什么错了,我将不胜感激。
auto& texture = r_textures[filename]
这将创建一个新的键值对,键为文件名。然后它将值分配给纹理,这是一个空值,因为没有加载纹理。
texture.loadFromFile(filename);
这将加载一个纹理文件并将其分配给纹理。这是我完全迷路的地方。这条线也以某种方式将纹理添加到键的值中。
然后它returns调用函数的纹理。
这可能更多是对SFML如何处理纹理对象的误解,但我仍然对这条线如何与地图中的键值对通信感到困惑。
auto& texture = r_textures[filename]
This creates a new key value pair with the key of filename. It then assigns the value to texture, which is an empty value since no texture has been loaded.
它不会将 值 分配给 texture
。它使 texture
成为对新创建的纹理的引用。这就是 auto&
中的 &
所做的。
texture.loadFromFile(filename);
This loads a texture file and assigns it to texture. This is where i'm completely lost. Some way this line is also adding the texture to the value of the key.
它没有将它分配给 texture
,而是将它分配给 texture
引用的对象——记住,texture
是一个引用。指贴图中的贴图。
Then it returns the texture to the calling function.
实际上,它 return 是对它的引用。请记住,return 类型是 sf::Texture&
.
auto& texture = r_textures[filename] This creates a new key value pair with the key of filename. It then assigns the value to texture, which is an empty value since no texture has been loaded.
不完全正确。 texture
是参考。它本身并不是一个谨慎的对象。
这将创建一个新的 key/value 对,并在映射中设置引用 texture
以引用新创建的值。
随后的 loadFromFile()
通过 texture
引用调用 loadFromFile()
方法。这恰好指的是地图中新插入的值。
然后,返回对从文件中新加载的值的引用。
胶囊摘要:它搜索地图以查看是否找到键,如果找到了 returns 对键值的引用。否则它会为那个键创建一个新的 key/value 对,初始化新值,然后 returns 它。
在此声明中
auto& texture = r_textures[filename];
在映射中创建了一个新对,键等于 filename
,映射值等于通过调用默认构造函数创建的对象 sf::Texture()
。运算符 returns 是对创建的映射值的引用。此引用存储在变量 texture
中,该变量又是一个引用。所以这个引用指的是映射类型的原始默认创建对象。
然后更新存储在映射中的映射类型的原始对象
texture.loadFromFile(filename);
因为变量texture
是对象的引用。
最后这个引用是映射中原始映射对象的引用从函数返回
return texture;
因此 operator []
returns 映射对象的引用(如果对应于指定键的对象已经存在于映射中)或者创建一个新的映射对象调用其默认构造函数并且还 returns 对新创建的映射对象的引用。
其他答案解释了您发布的代码。
然而,正如我的评论所建议的,使用 std::map::insert() 而不是 find()
然后 []
可能会使代码更清晰。诀窍是知道 std::map::insert
return 是什么以及如何使用它。
sf::Texture& TextureHolder::GetTexture(std::string const& filename)
{
auto& r_textures = m_s_instance -> m_textures;
// potentially insert a new texture. If not inserted, then the
// current one remains in the map
auto ret = r_textures.insert(std::make_pair(filename, sf::Texture()));
// ret is a std::pair<map::iterator, bool>, where map::iterator is
// the iterator to the existing or newly inserted item. The second
// is a bool that is either true or false, depending on whether new item
// was inserted or not.
// Now get the texture. A map's iterator is itself a pair, so
// 'first' of this pair is the filename, and 'second' is the texture.
auto& texture = ret.first->second;
// this tells us if it's a new item inserted
if ( ret.second )
texture.loadFromFile(filename);
return texture;
}
这基本上与您的版本做同样的事情,只是它使用 map::insert
来确定是否已插入新项目,并使用 insert
的 return 值继续前进.
请注意,map::insert
需要一个 std::pair
,它由 "potential" 新键和值组成(它是 "potential",因为我们不知道是否有新的是否插入密钥——我们让 insert() 决定)。
如果密钥已经存在,那么 insert
除了 return iterator/bool 对之外什么都不做。如果密钥不存在,则 insert
插入一个全新的 sf::Texture
默认构造一个(参见 make_pair
的第二个参数),然后是 iterator/bool 对是 returned.