2016-07-07 5 views
2

は、私は次のファイルの束を持っていると仮定しますバージョンのテンプレートクラスを使用して、使いやすさを簡素化します。正しい前方宣言

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

#include <Client.h> 

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

GenericMap何の前方宣言を持っていないテンプレートクラスを表します。クライアントコードはGeneric.hSpecial.h

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

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

main.cppには知っているかもしれません。一部のユーザーにとっては、完全に特殊化されたバージョンSpecialMapGenericMapであれば十分です。使いやすさのためにtypedefが使用されています。

Clientは内部でSpecialMapを使用しますが、ヘッダーファイルはSpecialMapの前方宣言のみを宣言する必要があります。

残念ながら、以下のファイルはコンパイルされません。どういうわけか、投稿された前方宣言で十分です。正しいものは何ですか?

長いリストは申し訳ありませんが、それは私が考えることができる最も小さな非実用的な例でした。

+0

私は '#pragma once'を推奨しません。移植性のために '#ifndef ... #define ... #endif'パターンを使用してください。 – erip

+0

'typedef'は特殊化を宣言しません。 –

+0

ヒントをありがとう。私の会社はVisual Studioのみを使用しています。移植性の問題はありません。 :-) – Aleph0

答えて

1

コメントでは、実際にC++の特殊化を指していないことを明確にしました。あなたはtypedefについてだけ質問していました:

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

これはかなりストーリーの終わりです。これは、SpecialMapがタイプエイリアスtypedefであると宣言します。 SpecialMapを使用する必要がある翻訳単位には、この型定義を含める必要があります。そして、この定義のみ。他に何もする必要はありません。他の方法で宣言する必要はありません。エイリアスです。 typedefエイリアスを基になる型で検索/置換すると、正確な結果が得られます。 1つの翻訳単位で宣言された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このヘッダーファイルだけでなく、実際にGenericMapテンプレートクラスを定義しているGeneric.hヘッダーも必要です。これは、ここで前方宣言されています。

+0

多くのありがとう。それは本当に私の問題を解決し、明確にします。以下の投稿されたコードを新しいヘッダーファイル 'SpecialMapFwd.h 'に含めます。 – Aleph0

+0

'GenericMap'にtypedef' typedef C map_type'が含まれているときに、私が何をしなくてはならないかを今すぐ考えようとしています。 'map_type'をどうやって宣言するのでしょうか? – Aleph0

+0

メインクラスを定義せずにクラスメンバーを宣言することはできません。 –