Fremder Source-Code: Fehler bei typedef



  • Ich hab hier fremden Source-Code, der bei mir allerdings nicht kompiliert. Und zwar kommt folgender Fehler:

    g++ -O0 -g3 -Wall -c -fmessage-length=0 -std=c++11 -o src\main.o ..\src\main.cpp
    In file included from ..\src\kdtree++/kdtree.hpp:61:0,
    from ..\src\main.cpp:10:
    ..\src\kdtree++/allocator.hpp:21:26: Fehler: Deklaration von »typedef struct KDTree::_Node<_Tp> KDTree::_Alloc_base<_Tp, _Alloc>::_Node« [-fpermissive]
    In file included from ..\src\kdtree++/allocator.hpp:12:0,
    from ..\src\kdtree++/kdtree.hpp:61,
    from ..\src\main.cpp:10:
    ..\src\kdtree++/node.hpp:48:12: Fehler: verändert die Bedeutung von »_Node« von »struct KDTree::_Node<_Tp>« [-fpermissive]

    allocator.hpp

    namespace KDTree
    {
    
      template <typename _Tp, typename _Alloc>
        class _Alloc_base
        {
        public:
          typedef _Node<_Tp> _Node; // Zeile 21
    

    node.hpp

    template <typename _Val>
        struct _Node : public _Node_base // Zeile 48
        {
    

    Muss ich "_Node" beim typedef zwingend umbennen oder gibt es noch andere Lösungen (vielleicht Parameter für den Compiler oder sowas)? Als Compiler benutze ich den g++ 4.7. Interessanterweise hat der Entwickler auch den g++ verwendet, allerdings eine deutlich ältere Version (der Code ist von 2007).

    Generell interessiert mich auch, ob so ein Überschreiben von _Node durch den typedef überhaupt standardkonform ist.



  • Ramanujan schrieb:

    Muss ich "_Node" beim typedef zwingend umbennen oder gibt es noch andere Lösungen (vielleicht Parameter für den Compiler oder sowas)?

    Steht in der Fehlermeldung: -fpermissive

    Interessanterweise hat der Entwickler auch den g++ verwendet, allerdings eine deutlich ältere Version (der Code ist von 2007).

    Es gibt keinen zwingenden technischen Grund, wieso das nicht erlaubt wäre und alte Compiler liessen noch einiges durchgehen, was nicht unbedingt standardkonform wäre.

    Generell interessiert mich auch, ob so ein Überschreiben von _Node durch den typedef überhaupt standardkonform ist.

    Nein. Nicht einmal der Name ist standardkonform, "_" gefolgt von Grossbuchstabe ist für die Implementierung reserviert.


  • Mod

    Wenn wir mal den reservierten Bezeichner ignorierten, sollte das vermutlich:

    typedef KDTree::_Node<_Tp> _Node; // Zeile 21
    

    heißen.

    Das Problem hier ist einfach, das sich die Bedeutung des tyoedefs ändert, je nachdem in welchem Kontext sieht betrachtet wird (an der Stelle der Deklaration oder nachdem _Alloc_base definiert wurde, 3.3.7/1 2) - ill-formed, keine Diegnose erforderlich).



  • Kennt jemand zufällig eine gute Implementierung von KD-Bäumen?
    Die jetztige scheint mir nicht so gut zu sein:

    Ich hab gleich den nächsten Fehler, den ich nicht verstehe:

    iterator.hpp

    class _Base_iterator
      {
      protected:
        typedef _Node_base::_Base_const_ptr _Base_const_ptr;
        _Base_const_ptr _M_node;
    
     template <size_t const __K, typename _Val,
                  typename _Acc, typename _Cmp, typename _Alloc>
          friend class KDTree;
    

    kdtree.hpp

    template <size_t const __K, typename _Val,
                typename _Acc = _Bracket_accessor<_Val>,
                typename _Cmp = std::less<typename _Acc::result_type>,
                typename _Alloc = std::allocator<_Node<_Val> > >
        class KDTree : protected _Alloc_base<_Val, _Alloc>
        {
    // [...]
    // Innerhalb einer Methode von KDTree:
    _Link_const_type target = static_cast<_Link_const_type>(__IT._M_node);
    

    Es kommt folgender Fehler:

    ..\src\kdtree++/iterator.hpp:53:21: error: 'const KDTree::_Node_base* KDTree::_Base_iterator::_M_node' is protected
    In file included from ..\src\main.cpp:10:0:
    ..\src\kdtree++/kdtree.hpp:271:77: error: within this context

    Da KDTree als Freund in dem _Base_iterator gekennzeichnet wurde, dachte ich, dass das funktionieren würde. Ich hab mal das "protected" in _Base_iterator auf "public" geändert, dann kommt aber immer noch ein Fehler:

    ..\src\kdtree++/iterator.hpp:53:21: error: 'const KDTree::_Node_base* KDTree::_Base_iterator::_M_node' is inaccessible
    In file included from ..\src\main.cpp:10:0:
    ..\src\kdtree++/kdtree.hpp:271:77: error: within this context

    Eine andere Frage hab ich noch: Ist ein Name, in dem _ gefolgt von einem Großbuchstaben in der Mitte vorkommt, standardkonform, also z.B. "XYZ_ABC"?


  • Mod

    _Link_const_type target = static_cast<_Link_const_type>(__IT._M_node);
    

    wie ist __IT deklariert und welcher Zugriffsspezifikation unterliegt _M_Node in _Base_iterator?

    Eine andere Frage hab ich noch: Ist ein Name, in dem _ gefolgt von einem Großbuchstaben in der Mitte vorkommt, standardkonform, also z.B. "XYZ_ABC"?

    ja. Reserviert sind
    1. Im globalen Namensraum jeder Bezeichner mit _ am Anfang
    2. Jeder Bezeichner mit _ am Anfang gefolgt von einem Großbuchstaben
    3. Jeder Bezeichner mit __ an irgendeiner Stelle des Namens



  • Danke, der Hinweis hat gereicht:

    __IT war vom Typ _Iterator (einer Unterklasse von _Base_iterator mit "protected"-Vererbung). Ich hab im _Iterator den KDTree als Friend markiert. Jetzt hab ich keine Fehler mehr beim Kompilieren.


  • Mod

    Edit: Unsinn, ich habe die Frage falsch gelesen.


Anmelden zum Antworten