2013-08-23 8 views
6

Ho una classe all'interno di un namespace in un file di intestazione. La classe richiede un tipo di modello e desidero solo che alcuni tipi vengano utilizzati. Di seguito è riportato un esempio.Classe privata nello spazio dei nomi

a.hpp File

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

b.hpp File

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

main.cpp File

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

Quindi, come potete vedere dalla piuttosto desiderava uscire esempio, la L'obiettivo finale è NON PERMETTERE all'utente finale di dichiarare uno class a con float come il d essere in grado di utilizzare solo le classi predefinite con tipi specifici, come dichiarato da typedef a<double> a_double;.

Ho pensato che questo esempio consentirebbe questo, tuttavia ho sbagliato, come posso creare un a<float> come sopra, perché includo b.hpp, che a sua volta include a.hpp! Quindi vedi il problema! (si spera?)

Probabilmente esiste una soluzione semplice, se possibile.

risposta

7

Se si desidera solo essere in grado di utilizzare gli alias di tipo e non usare a direttamente, si può mettere in un namespace implementazione che gli utenti dovrebbero sapere di non utilizzare:

namespace a_ns { 

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

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

Ora tutto può usare a_double, ma per utilizzare direttamente lo a, lo spazio dei nomi detail deve essere scavato, e questo è generalmente accettato come una cosa negativa da fare. Se un utente decide di volerlo fare, ha già rinunciato a stare fuori dai guai e non dovresti prendere ulteriori misure per impedirgli di ferirsi.

+1

In realtà mi piace - temo che non ci sia modo di sconfiggere i problemi dei programmatori. –

+0

@ DieterLücking, Una volta superato il fatto che devono scavare deliberatamente nel buco, inizi a preoccuparti molto meno di prevenirlo. Se vogliono lasciarsi andare, lasciali. Se c'è qualcosa che può davvero aiutarli, almeno ora non hanno bisogno di un trucco per raggiungerlo. – chris

+0

o come dice Herb Sutter: difendi contro Murphy, non Machiavelli – TemplateRex

0

Ecco come è possibile utilizzare uno 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; 
} 

Questo funzionerà fino a quando la variabile non è const o volatile,