簡體   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