简体   繁体   English

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

[英]Correct forward declaration of fully specialized template classes

Assume that I have the following bunch of files: 假设我有以下一堆文件:

Generic.h: Complicated template class 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: Define fully specialized version of mentioned template class, simplifying the ease of use. Special.h:定义所提到的模板类的完全专用版本,简化了易用性。

#pragma once

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

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

Client.h: Client that uses SpecialMap and define forward declaration. Client.h:使用SpecialMap并定义前向声明的客户端。

#pragma once

class SpecialMap; // Wrong forward declaration

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

Client.cpp: Clients code might know Generic.h and Special.h Client.cpp:客户端代码可能知道Generic.hSpecial.h

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

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

main.cpp: main.cpp中:

#include <Client.h>

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

GenericMap represents a template class that has no forward declaration. GenericMap表示没有前向声明的模板类。 For some users a fully specialized version SpecialMap of GenericMap should suffices, where for the ease of use a typedef is used. 对于一些用户SpecialMapGenericMap的完全专用版本SpecialMap应该足够,其中使用的是易于使用的typedef

Now Client uses internally SpecialMap , but the header file should only declare a forward declaration for SpecialMap . 现在Client内部使用SpecialMap ,但是头文件应该只声明SpecialMap的前向声明。

Unfortunately, the following files will not compile. 不幸的是,以下文件将无法编译。 Somehow the posted forward declaration will suffice. 不知何故,发布的前向声明就足够了。 What will be the correct one? 什么是正确的?

I'm sorry for the long listings, but it was the smallest non-working example I could think of. 对于很长的列表我很抱歉,但这是我能想到的最小的非工作示例。

In the comments you clarified that you were not actually referring to C++ specialization. 在评论中,您澄清说您实际上并没有提到C ++专业化。 You were asking merely about the typedef: 你只是询问typedef:

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

And that's pretty much the end of the story. 而这几乎就是故事的结尾。 This declares SpecialMap to be a typedef , a type alias. 这将SpecialMap声明为typedef ,类型别名。 Any translation unit that needs to use SpecialMap needs to include this type definition. 任何需要使用SpecialMap翻译单元都需要包含此类型定义。 And only this definition. 而且只有这个定义。 Nothing else needs to be done. 没有别的事情需要做。 It does not need to be declared in any other way. 它不需要以任何其他方式声明。 It is an alias. 这是一个别名。 A search/replace of the typedef alias with its underlying type produces the same exact results. 使用其基础类型搜索/替换typedef别名会产生相同的精确结果。 A typedef declared in one translation unit is visible only in that translation unit. 在一个翻译单元中声明的typedef仅在该翻译单元中可见。 There are no short-cuts for other translation units to import the typedef into their scope. 其他翻译单元没有捷径可以将typedef导入其范围。

In your Client.h: 在您的Client.h中:

#include <Special.h>

That's where you defined this typedef , and that's the only way to pull in this definition. 这就是你定义这个typedef的地方,这是引入这个定义的唯一方法。

However, this may also be the case where the typedef is a part of a larger header file, and it is desirable to pull in just the typedef, separately. 但是,这也可能是typedef是较大头文件的一部分的情况,并且希望单独引入typedef。 This could be done with a header file containing only: 这可以通过仅包含以下内容的头文件来完成:

#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;

This would be the bare minimum needed to define the typedef alias. 这将是定义typedef别名所需的最低限度。 Anything that actually needs to use it, will need to #include not just this header file, but also your Generic.h header, which actually defines the GenericMap template class, that's only forward-declared here. 任何实际需要使用它的东西,都需要#include不只是这个头文件,还需要你的Generic.h头,它实际上定义了GenericMap模板类,它只在这里进行了前向声明。

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

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