繁体   English   中英

正确的完全专业模板类的前向声明

[英]Correct forward declaration of fully specialized template classes

假设我有以下一堆文件:

Generic.h:复杂的模板类

#pragma once

template<typename K, typename V, template<typename Key, typename Value, typename ...> typename C>
struct GenericMap
{
    C<K, V> key;
};

Special.h:定义所提到的模板类的完全专用版本,简化了易用性。

#pragma once

#include "Generic.h"
#include <string>
#include <map>

typedef GenericMap<std::string, int, std::map> SpecialMap;

Client.h:使用SpecialMap并定义前向声明的客户端。

#pragma once

class SpecialMap; // Wrong forward declaration

struct Client {
    Client();
    SpecialMap* map;
};

Client.cpp:客户端代码可能知道Generic.hSpecial.h

#include "Client.h"
#include "Special.h"

Client::Client()
{
    map["343"] = 2;
}

main.cpp中:

#include <Client.h>

int main(int argc, char**args) {
    Client c;
    return 0;
}

GenericMap表示没有前向声明的模板类。 对于一些用户SpecialMapGenericMap的完全专用版本SpecialMap应该足够,其中使用的是易于使用的typedef

现在Client内部使用SpecialMap ,但是头文件应该只声明SpecialMap的前向声明。

不幸的是,以下文件将无法编译。 不知何故,发布的前向声明就足够了。 什么是正确的?

对于很长的列表我很抱歉,但这是我能想到的最小的非工作示例。

在评论中,您澄清说您实际上并没有提到C ++专业化。 你只是询问typedef:

typedef GenericMap<std::string, int, std::map> SpecialMap;

而这几乎就是故事的结尾。 这将SpecialMap声明为typedef ,类型别名。 任何需要使用SpecialMap翻译单元都需要包含此类型定义。 而且只有这个定义。 没有别的事情需要做。 它不需要以任何其他方式声明。 这是一个别名。 使用其基础类型搜索/替换typedef别名会产生相同的精确结果。 在一个翻译单元中声明的typedef仅在该翻译单元中可见。 其他翻译单元没有捷径可以将typedef导入其范围。

在您的Client.h中:

#include <Special.h>

这就是你定义这个typedef的地方,这是引入这个定义的唯一方法。

但是,这也可能是typedef是较大头文件的一部分的情况,并且希望单独引入typedef。 这可以通过仅包含以下内容的头文件来完成:

#include <string>
#include <map>

template<typename K, typename V,
        template<typename Key, typename Value, typename ...>
             typename C> struct GenericMap;

typedef GenericMap<std::string, int, std::map> SpecialMap;

这将是定义typedef别名所需的最低限度。 任何实际需要使用它的东西,都需要#include不只是这个头文件,还需要你的Generic.h头,它实际上定义了GenericMap模板类,它只在这里进行了前向声明。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM