2013-08-23 3 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 a с float в качестве имени, 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, ваше пространство имен должно быть выкопано, и это принято считать плохим делом. Если пользователь решает, что они хотят это сделать, они уже отказались от неприятностей, и вы не должны принимать дополнительные меры, чтобы помешать им причинить вред себе.

+1

На самом деле мне это нравится - боюсь, что не удастся победить программистов. –

+0

@ DieterLücking, Когда вы перейдете к факту, что они должны сознательно выкопать себя в яму, вы начинаете беспокоиться гораздо меньше о предотвращении этого. Если они захотят завязать себя, позвольте им. Если там что-то есть, что действительно может им помочь, по крайней мере сейчас им не нужен взлом, чтобы добраться до него. – chris

+0

или как Трава Саттер ставит это: защищать от Мерфи, а не Макиавелли – 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; 
} 

Это будет работать до тех пор, пока переменная не сопзЬ или неустойчивыми

Смежные вопросы