2013-08-23 24 views
6

私は、ヘッダーファイル内の名前空間内にクラスを持っています。クラスはテンプレート型を必要とし、特定の型のみを使用します。以下に例を示します。名前空間内のプライベートクラス

ファイルa.hpp

// a.hpp 
namespace a_ns { 
template<class T>  
class a { 
    // stuff 
}; 
typedef a<double> a_double; 
} // end of namespace 
// stuff 

ファイルb.hpp

// b.hpp 
#include <a.hpp> 
namespace b_ns { 
    typedef a_ns::a_double b; 
} 

ファイルmain.cppに

// main.cpp 
#include "b.hpp" 
int main() { 
    b_ns::b my_b; // <<<--- I LIKE this! 
    a_ns::a<float> my_a_which_is_not_allowed; // <<<--- I DO NOT LIKE THIS THOUGH! D: 
} 

ですから、むしろアウト憧れの例から見ることができるように最終目的はエンドユーザがclass afloatとタイプ名として宣言することを許可しないことです。 dは、typedef a<double> a_double;で宣言されているように、特定のタイプの事前定義されたクラスのみを使用できるようにします。

私はこれがを上記のように作成することができるので、私は間違っていましたが、これはa.hppを含むb.hppを含むためです。だからあなたは問題を見る! (うまくいけば?)

可能な限り単純な解決策があります。ここで

答えて

7

constまたはvolatileでないと動作します

あなたがstatic_assertを使用する方法
#include <type_traits> 
template <typename T> 
class X 
{ 
    T i; 
    static_assert(!std::is_same<float,T>::value,"Don't use floating point"); 
}; 



int main() 
{ 
    X<int> a; 
    //X<float> b; fails at compile time 
    return 0; 
} 

です何でも使用することができます今すぐ

namespace a_ns { 

namespace detail { 
    template<class T>   
    class a { 
     // stuff 
    }; 
} 

typedef detail::a<double> a_double; 
} // end of namespace 

a直接、ユーザーが使用しないように知っておくべき実装の名前空間にそれを置くことができます、しかしaを直接使用するには、あなたのdetail名前空間を掘り下げる必要があります。これは一般的には悪いことです。ユーザーがそれをしたいと決心した場合、彼らはすでに問題を抱えていることをあきらめてしまっており、あなたが自分を傷つけるのを防ぐために余分な措置をとるべきではありません。

+1

実際に私はこれが好きです - プログラマーを作る際のトラブルを克服する方法がないことを恐れています。 –

+0

@DieterLücking、あなたが意図的に自分自身を穴の中に掘り起こさなければならないという事実を乗り越えると、あなたはそれを防ぐことについて多くのことを心配し始めます。彼らが自分自身をねじ込む場合は、それらを聞かせてください。そこに実際に助けることができるものがあれば、少なくとも今はそれを得るためのハックは必要ありません。 – chris

+0

またはハーブサッターとしてそれを置く:マヒアヴェリではなく、マーフィーに対して守る – TemplateRex

0

これは限り、あなたは唯一の型の別名を使用することができ、および使用しないようにしたい場合は、変数が