Vim + OmniCppComplete: завершение для членов класса, которые являются контейнерами STL
Завершение для членов класса, которые являются контейнерами STL, терпит неудачу.
Завершение на локальных объектах, которые являются контейнерами STL, работает нормально.
Например, даны следующие файлы:
// 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 ----- */
Я сгенерировал теги для этих двух файлов, используя:
ctags -R --c++-kinds=+pl --fields=+iaS --extra=+q .
Когда я печатаю temp.
в CPP я получаю список string
член функционирует как ожидалось. Но если я наберу str.
omnicppcomplete выплевывает "шаблон не найден".
Я заметил, что temp.
завершение работает только если у меня есть using std::string;
декларация.
Как мне получить завершение работы над моими учениками, которые являются контейнерами STL?
редактировать
Я обнаружил, что завершение для членов, которые являются контейнерами STL, работает, если я внесу следующие изменения в заголовок:
// foo.h
#include <string>
using std::string;
class foo {
public:
void set_str(const string &);
string get_str_reverse( void );
private:
string str;
};
В принципе, если я добавлю using std::string;
а затем удалите std::
квалификатор пространства имен из string str;
член и восстановить файл тегов, то OmniCppComplete может завершить на str.
,
Кажется, не имеет значения, имею ли я let OmniCpp_DefaultNamespaces = ["std", "_GLIBCXX_STD"]
установить в .vimrc
,
Проблема в том, что положить using
объявления в заголовочных файлах кажутся большими нет-нет, так что я вернулся к исходной точке.
2 ответа
Недавно я перешел на Ubuntu 10.04, который включает в себя ctags 5.8, и у меня больше нет этой проблемы с классами STL, такими как string, однако завершение по-прежнему не работает с реальными контейнерами, такими как vector.
Это мой старый ответ на ctags 5.7:
Хотя это немного взломано, я нашел решение, которое не загрязняет заголовочные файлы using
директивы и предоставляет OmniCppComplete все, что нужно для завершения членов класса, которые являются контейнерами STL.
#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
Затем измените строку в .vimrc
файл, который генерирует ctags следующим образом:
map <C-F12> :!ctags -R --c++-kinds=+pl --fields=+iaS --extra=+q --if0=yes .<CR>
Как это работает? когда ctags
видит --if0=yes
вариант это займет #if 0
ветвь директивы препроцессора и создает необходимую запись в tags
файл:
str omnitest.h /^ string str;$/;" m class:foo access:private
OmniCppComplete видит подделку using std::string;
и когда он не может найти определение для string
это выглядит в std
пространство имен и находит его там.
И при компиляции с g++ вывод - это то, что мы хотим. Это можно проверить, запустив файлы через препроцессор:
$ g++ omnitest.cpp -E | less
В конце вы увидите:
# 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);
}
Так, например, если я наберу this->str.
в одной из функций-членов он теперь дает мне список строковых членов для завершения.
Этот метод может использоваться для любого набора контейнеров STL и даже может быть автоматизирован для изменения заголовка при регистрации или извлечении из хранилища Subversion с использованием сценария Perl.
Таким образом, ваши товарищи по команде не должны видеть ваши уродливые хаки:-)
Попробуйте установить эту переменную:
let OmniCpp_NamespaceSearch=1
Если это работает, не забудьте положить его в свой .vimrc
конфигурационный файл!