2010-07-23 8 views
8

Ich mag würde, so etwas bauen:„Templat“ ein Namespace

File 1: 
template<typename Vector> 
namespace myNamespace { 
    class myClass1{ myClass1(Vector v) {...} } 
} 

File 2: 
template<typename Vector> 
namespace myNamespace { 
    class myClass2{ myClass2(Vector v) {...} } 
} 

Natürlich ist dies nicht möglich, da man nicht Vorlage Namespaces. Stattdessen könnte ich eine Struktur anstelle eines Namespace verwenden, aber dann kann ich die Namespace-Funktionen nicht über mehrere Dateien verteilen.

Gibt es eine Lösung für ein solches Problem?

PS: Ich weiß, dass ich die Klassen anpassen könnte, aber dann müsste ich angeben, welchen Vektortyp ich verwenden möchte, wenn ich eine neue Klasse erstelle.

+1

In Bezug auf Ihre PS: Wie denken Sie, einen Templates-Namespace zu haben würde die Notwendigkeit, den Typ des Vektors anzugeben, wenn Sie Klassen instanziieren? Du brauchst immer noch so etwas wie einen (fiktiven) 'using namespace myNamespace ;' – stakx

+1

Ich bin dabei mit stakx. Und was ist das in deinem Code? – sbi

+0

Ja, aber Sie könnten etwas tun: int function1() { using namespace myNamespace ; myClass1 c1 = myClass1 (5); myClass2 c2 = myClass2 (2); } int function2() { Verwendung von Namespace myNamespace ; myClass1 c1 = myClass1 ('a'); myClass2 c2 = myClass2 ('b'); } Sorry, dass Int falsch ist, werde ich es löschen. Wie füge ich den Code hier richtig ein? – Manuel

Antwort

5

Im Anschluss an Ihrem Kommentar auf:

Statt zu schreiben

using namespace myNamespace<int>;

Nur Templat-Klassen verwenden und schreiben diese stattdessen (oder was auch immer Variation):

typedef myNamespace::myClass1<int> myClass1Int; 
typedef myNamespace::myClass2<int> myClass2Int; 

Ich neige dazu, denke, es ist besser, explizit zu sein, welche Arten verwendet werden, anstatt zu versuchen, etwas wie einen bestimmten Instant zu tun tiation eines Namensraums.

Können Sie das Problem, das Sie glauben lässt, dass Vorlagen-Namespaces nützlich wären, ausführlicher beschreiben?

Und denken Sie daran, Sie können immer eine make_myClass1 freie Funktion schreiben, um den Schablonentyp für Sie abzuleiten.

+0

Wahrscheinlich eine gute Idee. – Manuel

+2

@Mark B Ich weiß, das ist eine wirklich alte Frage, aber was ist, wenn Sie etwas wie eine 'Util'-Klasse mit nur statischen Methoden wollen?Wäre es nicht besser, einen Namespace zu verwenden? – AJC

2

Sie können das nicht tun, aber Sie können verschiedene Namespaces und typedefs bereitstellen (nicht, dass ich es befürworte).

namespace template_impl { 
    template <typename V> 
    class myClass1_tmpl {...}; 
    template <typename V> 
    class myClass2_tmpl {...}; 
} 
namespace myns_Vector1 { 
    typedef ::template_impl::myClass1_tmpl<Vector1> myClass1; 
    typedef ::template_impl::myClass2_tmpl<Vector1> myClass2; 
} 
void foo() { 
    using namespace myns_Vector1; 
    myClass1 mc1; 
} 
0

Wie auch immer, meine Klassen haben mehrere Template-Parameter. Jetzt habe ich diesen Ansatz:

#include <string> 
#include <iostream> 

namespace myNamespace { 
    template<typename _integer, typename _string> 
    struct s { 
    typedef _integer integer; 
    typedef _string string; 
    }; 

    template<class T> 
    class classA { 
    public: 
    static typename T::integer intFunc() { return 1; } 
    static typename T::string stringFunc() { return "hallo"; } 
    }; 
} 


int main() { 
    using namespace myNamespace; 

    typedef s<int, std::string> types1; 
    typedef s<unsigned int, char*> types2; 

    std::cout << classA<types1>::intFunc() << std::endl; 
    std::cout << classA<types1>::stringFunc() << std::endl; 

    std::cout << classA<types2>::intFunc() << std::endl; 
    std::cout << classA<types2>::stringFunc() << std::endl; 

} 

und ich denke, ich es mit Mark B Ansatz kombinieren werden!

Prost, Jungs!

Verwandte Themen