2017-06-30 3 views
1

Ich schaute mich um und versuchte eine Antwort darauf zu finden. Ist es möglich, die Member-Funktionen einer Template-Klasse in einem Namespace innerhalb einer cpp-Datei zu definieren? Ich bekomme einen Fehler, wenn ich es versuche.Vorlagenelement-Memberfunktionen in einem Namespace definieren?

Hier sind die zwei Dateien, die ich versuche zu kompilieren.

ArrayList.hpp

 template<typename T> 
    class ArrayList{ 
      ArrayList(); 
      ~ArrayList(); 
    } 

ArrayList.cpp

#include "ArrayList.hpp" 

    namespace{ 

     template<typename T> 
     ArrayList<T>::ArrayList(){ 

     /* function body goes here */ 

     } 

     ArrayList<T>::~ArrayList(){ 

     /* function body goes here */ 

     } 

Compilerfehler

error: cannot define or 
    redeclare 'ArrayList<T>' here because namespace '' does not enclose 
    namespace 'ArrayList' 
    ArrayList<T>::ArrayList() 
+0

Namespace benannt werden sollte, das heißt: 'Namespace myarray {' – Serge

+0

@Serge Sie anonyme Namespaces in C haben kann ++ auch – Curious

+0

@Serge führt zu einem ähnlichen Fehler -> ‚kann nicht definieren oder neu deklarieren‚Arraylist ‘hier Weil Namespace 'myarray' nicht umschließt Namespace 'ArrayList' ArrayList :: ArrayList() ' – user87002

Antwort

3

Sie müssen Ihre Klasse im selben Namespace deklarieren, in dem Sie ihre Mitgliedsfunktionen definieren.

Und Sie vermissen eine template<typename T> vor Ihrem Destruktor.

namespace ANamespace 
{ 

    template<typename T> 
    class ArrayList 
    { 
     ArrayList(); 
     ~ArrayList(); 
    }; 

    template<typename T> 
    ArrayList<T>::ArrayList() 
    { 

     /* function body goes here */ 

    } 

    template<typename T> 
    ArrayList<T>::~ArrayList() 
    { 

     /* function body goes here */ 

    } 
} 
1

Zum einen können Sie keine Template-Klasse Methoden in einer .cpp Datei definieren. Sie benötigen Template-Klasse Methoden in der Header-Datei selbst definieren (oder in einer anderen Datei und importieren Sie dann, dass über Präprozessor in der Header-Datei enthält selbst) Für mehr sehen Why can templates only be implemented in the header file?

Anonyme Namespaces namespace { verwendet werden, Dinge zu definieren, die interne Bindung haben , dh ähnlich dem Effekt static hat auf Funktionen in Implementierungsdateien definiert. Weitere Informationen hierzu finden Sie unter Why are unnamed namespaces used and what are their benefits?

In Ihrem Fall möchten Sie jedoch die Klassenmethoden so definieren, dass sie extern sichtbar sind, da Sie sie in der Headerdatei öffentlich deklariert haben. Daher möchten Sie diese Definitionen wahrscheinlich nicht in einem anonymen Namespace haben.

Wenn Sie einen Namespace-Klasse in Ihrem Header-Datei einschließt, zum Beispiel namespace array_list dann sollten Sie nur Klassenmethoden im selben Namespace in der Header-Datei definiert sich, da es eine Template-Klasse ist und muss sichtbar sein, wo immer benutzt.

2

Ist es möglich, die Memberfunktionen einer Template-Klasse in einem Namespace innerhalb einer cpp-Datei zu definieren?

Nein, das ist nicht möglich. Wie bei allen anderen Klassendeklarationen müssen die Memberfunktionsdeklarationen und ihre Definitionen im selben Namespace erscheinen.

Auch unbenannte Namespaces, wie in Ihrem Beispiel verwendet, werden nur in dieser bestimmten Übersetzungseinheit angezeigt.

Sie können Schablonendefinitionen im Allgemeinen nicht in separate Übersetzungseinheiten einfügen (es sei denn, Sie haben spezielle Spezialisierungsfälle). Lesen Sie mehr dazu hier bitte:

Why can templates only be implemented in the header file?


Wie es zu beheben?

einfach alles zu Ihrer Header-Datei verschieben und die unbenannte Namespace wie folgt löschen:

Arraylist.HPP

template<typename T> 
class ArrayList{ 
     ArrayList(); 
     ~ArrayList(); 
}; // Semicolon at end of class declaration is essential 

template<typename T> 
ArrayList<T>::ArrayList(){ 
    /* function body goes here */ 
} 

template<typename T> // <<<<< Repeat for evey function definition 
ArrayList<T>::~ArrayList(){ 
    /* function body goes here */ 
} 

Wenn Sie wirklich einen Namensraum haben wollen, bieten nur einen Namen ein und alles einschließen von oben (noch im Header):

namespace MyUtilities { 
    template<typename T> 
    class ArrayList{ 
    public: // <<<<<< Allow access to these functions 
      ArrayList(); 
      ~ArrayList(); 
    }; 

    template<typename T> 
    ArrayList<T>::ArrayList(){ 
      /* function body goes here */ 
    } 

    template<typename T> 
    ArrayList<T>::~ArrayList(){ 
     /* function body goes here */ 
    } 
} 

Siehe voll funktionsfähiges Beispiel here bitte.

Verwenden Sie auch das Schlüsselwort public, um das Zeug nutzbar zu machen, wie oben gezeigt.

Verwandte Themen