在相应的源文件中使用头文件中的别名

时间:2018-12-11 16:42:54

标签: c++

我刚刚开始学习更多有关c ++的知识,并正在编写一个小型渲染引擎作为案例研究。当我开始实现更多代码时,我被键入

std::vector<std::vector<int>>

一遍又一遍。众所周知,如果您遍历上述向量,这种情况将变得更加无穷

for (std::vector<std::vector<Tile>>::const_iterator layerRow = ...) {}

由于这不仅烦人而且容易出错,因此我遵循Scott Meyers在“更有效的C ++”中的建议,研究使用typedef,并很快将其更改为别名。 我现在遇到一个问题,似乎无法解决问题。给定以下两个文件(对应的头文件和源文件):

map.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);
}

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

函数generateTileMapLayer()可以正常编译,没有问题。一旦实现getTileLayer(),UI就会给我一个错误“标识符'tileLayerVector_t'未定义”,而编译器也给我一些关于缺少“;”的奇怪错误。某处。如果我在注释中放入getTileLayer(),此编译器错误将消失。 我不明白为什么可以在函数generateTileMapLayer()中使用别名作为哈希映射的类型定义,但不能将其用作getTileLayer()的返回类型。我把Map :: tileLayerVector_t作为返回类型,它可以工作。为什么在没有generateTileMapLayer()中的命名空间的情况下仍能正常工作?

也许有人可以帮助我。预先谢谢你!

1 个答案:

答案 0 :(得分:3)

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

因此,当您在using tileLayerVector_t = ...;内声明 class Map时,将为新类型Map::tileLayerVector提供别名。

这就是为什么您的代码 inside 可以不加限制地使用类型,而代码 outside 却不能。

您可以将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
{
    ....
}