2016-08-22 14 views
1

私は、C++ 11/14を学んでいるときにやっている少しのコードでちょっとした問題に遭遇しました。基本的には、すべてのメッセージ印刷を処理するデバッグクラスがあります。ほとんどのデバッグ/ロギングクラスにはログレベルのソートがありますが、にはそれぞれというメッセージがあります。私は私が私のフラグとその値を定義少し列挙持っていることについてはクラスの部分テンプレートの二重特殊化

enum DebugFlag { 
    Flag1 = 0, 
    Flag2 = 1, 
    Flag3 = 2 
}; 

Aditionallyを、私は旗のタイプのために特化するために管理してきたデバッグクラスを、持っているし、それはかなりうまく動作します。このクラスを呼び出すために

template<DebugFlag T> 
class Debug { 
public: 
    template <typename U> 
    static void print(U &&arg) {} 
}; 

template <> 
class Debug<static_cast<DebugFlag>(1)> { 
public: 
    static void print(std::string &&message) { 
     std::cerr<<message<<"\n"; 
    } 

    static void print(std::ostream &message) { 
     std::cerr<<DebugStream()().str()<<"\n"; 
     DebugStream()().str(""); 
     DebugStream()().clear(); 
    } 

    static void print(std::string &message) { 
     std::cerr<<message<<"\n"; 
    } 
}; 

は、私は次のように呼び出しを使用します。

Debug<Flag1>::print("Message\n"); // should not do anything with Flag1 compiled to 0 value 
Debug<Flag2>::print("Message\n"); // should work 

今、私はこのような呼び出しが動作しますので、またbool値を取るために、このクラスを拡張したい:

Debug< Flag2<2 >::print("Message\n"); // should not do anything with Flag1 compiled to 2 value 
Debug< Flag2<1 >::print("Message\n"); // should work 

問題は、私のデバッグクラスの2番目の部分的な特殊化、つまりboolが必要で、これが何のための構文なのか正確には分かりません。 これは私がそれに来て一番近いですが、まだそれが二次クラスを作り、私は私の呼び出しは次のようになりたい方法を変更することなく可能だ場合、私が間違ってやっているかを把握たりすることはできません。http://cpp.sh/6yemn

答えて

2

あなたのクラスをどのように使いたいか正確にはわかりませんが、ここではうまくいくものがあります。あなたがboolFlagを使用するかどうか、およびその値:

template <typename T, T v = T()> 
class Debug {}; 

template <> 
class Debug<Flag, Flag2> { 
public: 
    void f() { std::cout<<"This is good\n"; } 
}; 

template <> 
class Debug<bool, true> { 
public: 
    void f() { std::cout<<"This is good too\n"; } 
}; 

問題は、タイプを指定する必要があるということです。あなたはそうのようなクラスをインスタンス化することができます:あなたが専門分野を追加しない限り

Debug<bool, true> trueDebug; 
Debug<Flag, Flag2> flag2Debug; 

他のインスタンスがf機能を持っていません。たとえば、次のように

template <Flag v> 
class Debug<Flag, v> { 
public: 
    void f() { std::cout<<"This is bad\n"; } 
}; 

Live example

+0

こんにちは、返信いただきありがとうございます。多分、この例を 'Debug '、 'int'、' Flag'の例と混同しているかもしれません。実際には私の呼び出しは 'Debug '、 'Debug '、 'Debug 'のいずれかになります。 私があなたの回答から収集したのは、1つのテンプレートパラメータを使用して、2つの異なるタイプの2つの部分的な実装(ブール値がtrueで、すべてのフラグが1に等しいすべてのフラグ)を持つ方法がないことです。質問、動作しているリンクではありません)。 –

+0

C++ 17は最初のパラメータを取り除くことができるので、期待される構文を持つことができます。 ( 'template class Debug;') – Jarod42

+0

私の好奇心のために、何を検索するのか、あるいはC++ドラフトのリンクを提供するのを教えてください。私は実際何か解決できるように見えるので、この特定の問題を数時間で探しました。 悲しいことに、私はこれを '#defined'を使って非常に簡単に行うことができたと思いますが、const/constexprとテンプレートのためにC++でそれらを完全に避けようとしていますが、 。 –

関連する問題