2013-08-23 49 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<float>,因爲我包含了b.hpp,它又包含a.hpp!所以你看到了問題! (希望是?)

可能有一個簡單的解決方案,如果這是可能的話。

回答

7

工作a直接,你可以把它變成一個實現的命名空間,用戶應該知道不要使用:

namespace a_ns { 

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

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

現在什麼都可以使用a_double,但直接使用a,則需要挖掘detail命名空間,這通常被認爲是一件壞事。如果用戶決定要這樣做,他們已經放棄了避免麻煩,並且不應該採取額外的措施來阻止他們傷害自己。

+1

其實我喜歡這樣 - 我害怕沒有辦法打敗編程人員的麻煩。 –

+0

@DieterLücking,一旦你克服了他們不得不故意將自己挖入洞中的事實,你開始擔心更多的擔心阻止它。如果他們想把自己搞砸,讓他們。如果那裏有東西能夠真正幫助他們,至少現在他們不需要黑客就可以達到目的。 – chris

+0

或者Herb Sutter所說的:保護墨菲,而不是馬基雅維利 – TemplateRex

0

這裏是你如何使用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; 
} 

如果你只是希望能夠使用類型別名,而不是使用這隻要變量不是常量或揮發性