2010-05-16 10 views
11

Abschluss für Klassenmitglieder, die STL-Container sind, schlägt fehl.Vim + OmniCppComplete: Abgeschlossen für Klassenmitglieder, die STL-Container sind

Abschluss auf lokalen Objekten, die STL-Container sind, funktioniert gut.

Zum Beispiel angesichts der folgenden Dateien:

// foo.h 
#include <string> 

class foo { 
public: 
    void set_str(const std::string &); 

    std::string get_str_reverse(void); 

private: 
    std::string str; 
}; 

// foo.cpp 
#include "foo.h" 

using std::string; 

string 
foo::get_str_reverse (void) 
{ 
    string temp; 

    temp.assign(str); 
    reverse(temp.begin(), temp.end()); 

    return temp; 
}  /* ----- end of method foo::get_str ----- */ 

void 
foo::set_str (const string &s) 
{ 
    str.assign(s); 
}  /* ----- end of method foo::set_str ----- */ 

ich die Tags für diese beiden Dateien erzeugt haben mit:

ctags -R --c++-kinds=+pl --fields=+iaS --extra=+q . 

Als ich temp. in der CPP-Typ erhalte ich eine Liste von string Mitglied funktioniert wie erwartet. Aber wenn ich str. omnicppcomplete spucke spuckt "Muster nicht gefunden" aus.

Ich habe festgestellt, dass die temp. Vervollständigung funktioniert nur, wenn ich die using std::string; Deklaration habe.

Wie bekomme ich die Fertigstellung, um an meinen Klassenmitgliedern zu arbeiten, die STL-Container sind?

bearbeiten

fand ich, dass die Fertigstellung auf Mitglieder, die STL-Container sind funktioniert, wenn ich die folgen Änderungen an der Header machen:

// foo.h 
#include <string> 

using std::string; 

class foo { 
public: 
    void set_str(const string &); 

    string get_str_reverse(void); 

private: 
    string str; 
}; 

Grundsätzlich, wenn ich using std::string; hinzufügen und entfernen dann die std:: Namespace-Qualifikationsmerkmal aus dem Member string str; und die Tag-Datei neu generieren, dann kann OmniCppComplete die Fertigstellung unter str. ausführen.

Es scheint nicht wichtig zu sein, ob ich let OmniCpp_DefaultNamespaces = ["std", "_GLIBCXX_STD"] im .vimrc gesetzt habe oder nicht.

Das Problem ist, dass using Deklarationen in Header-Dateien scheint wie ein großes Nein, also bin ich wieder auf Platz eins.

+0

Komische Ihre hässlichen Hacks zu sehen: Ich habe versucht, den Test und für mich ist es genau das Gegenteil! str funktioniert und temp nicht ... welche version von ctags benutzt du übrigens? – UncleZeiv

+0

tatsächlich temp funktioniert auch, wenn ich ': OmniCpp_DefaultNamespaces = [" Std "]' – UncleZeiv

+0

@UncleZeiv: Ich benutze Ctags 5.7 auf Ubuntu 8.04. Ich fand, dass es egal ist, ob ich Default_Namespaces gesetzt habe oder nicht. Siehe meine Bearbeitung oben. –

Antwort

0

Versuchen Sie, diese Stellgröße:

let OmniCpp_NamespaceSearch=1 

Wenn es funktioniert, vergessen Sie nicht, es in Ihrer .vimrc Konfigurationsdatei zu setzen!

+0

Ich hatte das schon eingeschaltet und es macht keinen Unterschied. –

+0

Ich habe eine Lösung gefunden, wenn Sie interessiert sind. –

+0

Kannst du es hier posten? –

1

Ich zog vor kurzem zu Ubuntu 10.04, die Ctags 5.8 enthält und ich habe dieses Problem nicht mehr mit STL-Klassen wie string, aber die Fertigstellung funktioniert noch nicht wirklich Container wie Vektor.

Das ist meine alte Antwort für ctags 5.7:

Zwar ist es ein bisschen wie ein Hack ist, ich habe eine Lösung gefunden, die nicht die Header-Dateien mit using Richtlinien nicht verschmutzen und bietet OmniCppComplete mit allem, was es muss Klassenmitglieder vervollständigen, die STL-Container sind.

#include <string> 

#if 0 
using std::string; 
#else 
# define string std::string 
#endif 

class foo { 
public: 
    void set_str(const string &); 

    string get_str_reverse(void); 

private: 
    string str; 
}; 

#ifdef string 
# undef string 
#endif 

dann die Zeile in der .vimrc Datei ändern, die die ctags erzeugt wie folgt:

map <C-F12> :!ctags -R --c++-kinds=+pl --fields=+iaS --extra=+q --if0=yes .<CR> 

Wie funktionierts? Wenn ctags die --if0=yes Option sieht, wird es dauern, die #if 0 Zweig der Präprozessordirektive und erzeugt den notwendigen Eintrag in der Datei tags:

str omnitest.h /^ string str;$/;" m class:foo access:private 

OmniCppComplete die gefälschte using std::string; sieht und wenn sie nicht finden kann es eine Definition für string sucht im Namespace std und findet es dort.

Und beim Kompilieren mit g ++ ist die Ausgabe, was wir wollen. Dies kann durch Ausführen der Dateien durch den Prä-Prozessor überprüft werden:

$ g++ omnitest.cpp -E | less 

Am Ende werden Sie sehen:

# 2 "omnitest.h" 2 

class foo { 
public: 
    void set_str(const std::string &); 

    std::string get_str_reverse(void); 

private: 
    std::string str; 
}; 
# 2 "omnitest.cpp" 2 

using std::string; 

string foo::get_str_reverse (void) 
{ 
    string temp; 

    temp.assign(str); 
    reverse(temp.begin(), temp.end()); 

    return temp; 
} 

void foo::set_str (const string &s) 
{ 
    str.assign(s); 
} 

So zum Beispiel, wenn ich tippe this->str. in einem der Mitgliedsfunktionen es jetzt gibt mir eine Liste von String-Mitgliedern, von denen ich vervollständigen kann.

Diese Technik kann für jeden Satz von STL-Containern verwendet werden und könnte sogar automatisiert werden, um den Header beim Einchecken oder Auschecken aus einem Subversion-Repository mithilfe eines Perl-Skripts zu ändern.

Auf diese Weise Ihren Teamkollegen brauchen nicht :-)

+0

gut ... es ist wirklich ein schrecklicher hack! :) Ich verwende oft #if 0, um Dinge zu kommentieren, damit ich diese bestimmte Definition nicht verwenden würde. Abgesehen davon bin ich froh, dass du eine Lösung gefunden hast, die zu dir passt, aber ich frage mich immer noch, warum ich deinen Fehler nicht reproduzieren kann ... wenn ich andere Ideen habe, was in deiner Umgebung falsch sein könnte, werde ich dich wissen lassen :) – UncleZeiv