2013-08-23 17 views
6

Mam klasy w przestrzeni nazw w pliku nagłówkowym. Klasa wymaga typu szablonu i chcę, aby tylko niektóre typy były używane. Poniżej pokazano przykład.Prywatna klasa w przestrzeni nazw

a.hpp pliku

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

b.hpp pliku

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

main.cpp pliku

// 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: 
} 

Więc jak widać z zewnątrz raczej tęsknił przykładu, celem końcowym jest NIE POZWALAĆ użytkownikowi końcowemu do zadeklarowania class a z float jako nazwy d, aby móc używać tylko predefiniowanych klas z określonymi typami, zgodnie z deklaracją typedef a<double> a_double;.

Pomyślałem, że powyższy przykład na to pozwoli, jednak myliłem się, ponieważ mogę utworzyć a<float> jak wyżej, ponieważ włączam b.hpp, który z kolei obejmuje a.hpp! Więc widzisz problem! (mam nadzieję?)

Prawdopodobnie istnieje proste rozwiązanie, jeśli jest to w ogóle możliwe.

Odpowiedz

7

Jeśli chcesz tylko, aby móc używać aliasów typu i nie używać a bezpośrednio, można umieścić go w przestrzeni nazw realizacji, które użytkownicy powinni wiedzieć, aby nie używać:

namespace a_ns { 

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

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

teraz wszystko może używać a_double, ale aby bezpośrednio użyć a, należy wymazać przestrzeń nazw, która jest ogólnie akceptowana jako coś złego. Jeśli użytkownik zdecyduje, że chce to zrobić, już zrezygnował z pozostawania z dala od kłopotów i nie należy podejmować dodatkowych środków, aby powstrzymać ich od zranienia się.

+1

Właściwie to lubię - obawiam się, że nie da się pokonać kłopotów z programistami. –

+0

@ DieterLücking, Gdy już się przekonasz, że muszą celowo wkopać się w dziurę, zaczynasz niepokoić się o wiele mniej. Jeśli chcą się przewrócić, pozwól im. Jeśli jest coś, co naprawdę może im pomóc, przynajmniej teraz nie potrzebują hakowania, aby do niego dotrzeć. – chris

+0

lub jak mówi Herb Sutter: bronić się przed Murphy, nie Machiavelli – TemplateRex

0

Oto jak można użyć 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; 
} 

to będzie działać tak długo, jak zmienna nie jest const lub volatile