在相应的源文件中使用头文件中的别名 我刚刚开始学习C++,并且正在编写一个小型的渲染引擎作为例子。当我开始实现更多的代码时,我对键入以下类型感到恼火 std::vector<std::vector<int>> std::vector

在相应的源文件中使用头文件中的别名 我刚刚开始学习C++,并且正在编写一个小型的渲染引擎作为例子。当我开始实现更多的代码时,我对键入以下类型感到恼火 std::vector<std::vector<int>> std::vector,c++,C++,一遍又一遍。正如你们中的大多数人已经知道的,如果你们在所说的向量上循环,这个结果会变得非常糟糕 for (std::vector<std::vector<Tile>>::const_iterator layerRow = ...) {} for(std::vector::const_迭代器layerRow=…){ 因为这不仅令人讨厌,而且非常容易出错,所以我研究了使用typedef,并很快按照Scott Meyers在“更有效的C++”中的建议将其改为alias。 我

一遍又一遍。正如你们中的大多数人已经知道的,如果你们在所说的向量上循环,这个结果会变得非常糟糕

for (std::vector<std::vector<Tile>>::const_iterator layerRow = ...) {}
for(std::vector::const_迭代器layerRow=…){
因为这不仅令人讨厌,而且非常容易出错,所以我研究了使用typedef,并很快按照Scott Meyers在“更有效的C++”中的建议将其改为alias。 我现在有一个问题,我似乎无法解决。给定以下两个文件(对应的头文件和源文件):

地图h:

class Map
{
  public:
    using tileLayerVector_t = std::vector<std::vector<Tile>>;
    using rawDataLayerVector_t = std::vector<std::vector<int>>;
    tileLayerVector_t getTileLayer(const std::string pLayerName) const;
    void generateTileMapLayer(const std::string pMapLayerName, const rawDataLayerVector_t pRawMapData, const std::shared_ptr<Texture> pTexture);
}
类映射
{
公众:
使用tileLayerVector_t=std::vector;
使用rawDataLayerVector_t=std::vector;
tileLayerVector\u t getTileLayer(常量std::string pLayerName)常量;
void generatilemaplayer(const std::string pMapLayerName,const rawDataLayerVector\u t pRawMapData,const std::shared\u ptr pTexture);
}
map.cpp:

#include <map.h>

tileLayerVector_t Map::getTileLayer(const std::string pLayerName) const
{
  return mapLayers.at(pLayerName);
}


void Map::generateTileMapLayer(const std::string pMapLayerName, const 
rawDataLayerVector_t pRawMapData, const std::shared_ptr<Texture> pTexture)
{
  int tileCount = 0;
  int xPos = 0;
  int yPos = 0;

  ...

  std::pair<std::string, tileLayerVector_t> tileLayer(pMapLayerName, tileMapLayer);
  mapLayers.insert(tileLayer);
}   
#包括
tileLayerVector\u t映射::getTileLayer(常量std::字符串播放器名称)常量
{
返回mapLayers.at(pLayerName);
}
无效映射::GenerateTimeMaplayer(常量std::字符串pMapLayerName,常量
rawDataLayerVector\u t pRawMapData,常数std::shared\u ptr pTexture)
{
int tileCount=0;
int xPos=0;
int-yPos=0;
...
std::pair tileLayer(pMapLayerName,tileMapLayer);
mapLayers.insert(tileLayer);
}   
函数generateTileMapLayer()编译良好,没有问题。当我实现getTileLayer()时,UI会给我一个错误“标识符'tileLayerVector_t'未定义”,编译器会给我一些关于某个地方缺少“;”的奇怪错误。如果我将getTileLayer()放入注释中,此编译器错误将消失。 我不明白为什么我可以在函数GenerateTimeLayer()中使用别名作为哈希映射的类型定义,但不能将其作为getTileLayer()的返回类型。我将Map::tileLayerVector\u t作为返回类型,它可以工作。但是为什么它在GenerateTimeLayer()中没有名称空间就可以工作


也许有人能帮我。提前谢谢你

类定义了一个作用域。如何访问给定范围内的内容取决于您是在该范围内还是在该范围外编写代码

因此,当您使用tileLayerVector_t=…,进行声明时,
类映射中
为新类型
映射::tileLayerVector
提供别名

这就是为什么类内的代码可以在没有限定的情况下使用类型,而类外的代码不能

可以将using声明移到类之外,但这会污染全局命名空间。我认为,更好的解决方案是在需要的地方对类型进行限定:

Map::tileLayerVector_t Map::getTileLayer(...) // must qualify type here
{
    tileLayerVector_t temp = ...; // inside a class method, no problem here
}
更现代的解决方案是使用“类型推断”。我相信你至少需要一个兼容C++11的编译器来利用这个特性。我的理解是,尾随返回类型允许编译器推迟建立实际类型,直到生成函数签名之后,此时范围已经建立

auto Map::getTileLayer(...) -> tileLayerVector_t
{
    ....
}

类定义了一个作用域。如何访问给定范围内的内容取决于您是在该范围内还是在该范围外编写代码

因此,当您使用tileLayerVector_t=…,进行声明时,
类映射中
为新类型
映射::tileLayerVector
提供别名

这就是为什么类内的代码可以在没有限定的情况下使用类型,而类外的代码不能

可以将using声明移到类之外,但这会污染全局命名空间。我认为,更好的解决方案是在需要的地方对类型进行限定:

Map::tileLayerVector_t Map::getTileLayer(...) // must qualify type here
{
    tileLayerVector_t temp = ...; // inside a class method, no problem here
}
更现代的解决方案是使用“类型推断”。我相信你至少需要一个兼容C++11的编译器来利用这个特性。我的理解是,尾随返回类型允许编译器推迟建立实际类型,直到生成函数签名之后,此时范围已经建立

auto Map::getTileLayer(...) -> tileLayerVector_t
{
    ....
}

Tim Randall我也试过typedef的,但都是一样的问题,投反对票的人怎么了?来吧,伙计们。这是一个具体且描述良好的问题。仅仅因为你知道答案并不是否决投票的理由!是的,关于反对票。我提交了答案,15秒后投了两张反对票……有人在玩他们的鼠标,我想xDI从来没有用过
typedef
@Tim Randall我也用typedef试过,但问题是一样的。反对票怎么了?来吧,伙计们。这是一个具体且描述良好的问题。仅仅因为你知道答案并不是否决投票的理由!是的,关于反对票。我提交了答案,15秒后投了两张反对票……有人玩得很开心,我想谢谢你的澄清。我认为它可以在方法内部工作,因为该方法在名称空间映射中,但返回参数不在名称空间映射中。不过我不确定。谢谢你帮助我!:)<代码>自动映射::getTileLayer(…)->tileLayerVector\u t也可以,如果您愿意的话。谢谢您的澄清。我认为它可以在方法内部工作,因为该方法在名称空间映射中,但返回参数不在名称空间映射中。不过我不确定。谢谢你帮助我!:)<代码>自动映射::getTileLayer(…)->tileLayerVector\u t也可以,如果你愿意的话。