2010-07-23 8 views
8

Je voudrais construire quelque chose comme ceci:« templating » un espace de noms

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

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

Bien sûr, cela est impossible, car vous ne pouvez pas namespaces modèle. Au lieu de cela, je pourrais utiliser une structure au lieu d'un espace de noms, mais je ne peux pas étendre les fonctions de l'espace de noms sur plusieurs fichiers.

Y a-t-il une solution à un tel problème? PS: Je sais que je pourrais modéliser les classes, mais alors je devrais spécifier quel type de vecteur je veux utiliser chaque fois que je crée une nouvelle classe.

+1

En ce qui concerne votre PS: Comment pensez-vous qu'avoir un espace de noms basé sur un modèle supprimerait le besoin de spécifier le type de vecteur lorsque vous instanciez des classes? Vous auriez toujours besoin d'au moins quelque chose comme un (fictif) 'using namespace myNamespace ;' – stakx

+1

Je suis avec stakx sur ceci. Et quel est ce 'int' dans votre code? – sbi

+0

Oui, mais alors vous pourriez faire quelque chose comme ceci: int function1() { en utilisant l'espace de noms myNamespace ; myClass1 c1 = myClass1 (5); myClass2 c2 = myClass2 (2); } int fonction2() { en utilisant l'espace de noms myNamespace ; myClass1 c1 = myClass1 ('a'); myClass2 c2 = myClass2 ('b'); } Désolé, que int est faux, je vais le supprimer. Comment coller du code ici correctement? – Manuel

Répondre

5

suite à votre commentaire:

Au lieu d'écrire

using namespace myNamespace<int>;

Juste utiliser des classes templated et écrire à la place (ou tout autre variation):

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

J'ai tendance à pense qu'il est préférable d'être explicite sur les types qui sont utilisés plutôt que d'essayer de faire quelque chose comme importer un instan particulier tiation d'un espace de noms. Pouvez-vous décrire plus en détail le problème qui vous fait penser que les espaces de noms basés sur des modèles seraient utiles?

Et rappelez-vous que vous pouvez toujours écrire une fonction libre make_myClass1 pour en déduire le type de modèle.

+0

Probablement une bonne idée. – Manuel

+2

@Mark B Je sais que c'est une question vraiment ancienne, mais que faire si vous voulez quelque chose comme une classe 'Util' avec seulement des méthodes statiques?Est-ce que l'utilisation d'un espace de noms ne serait pas meilleure pour ça? – AJC

2

Vous ne pouvez pas faire cela, mais vous pouvez fournir différents espaces de noms et typedefs (pas que je l'entérine).

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

Quoi qu'il en soit, mes classes ont plusieurs paramètres de gabarit. Maintenant, je crée cette approche:

#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; 

} 

et je crois que je vais l'associer à l'approche de Mark B!

Cheers, les gars!