作为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 .
当我在cpp中输入temp.
时,我会按预期获得string
成员函数列表。但是如果我输入str.
omnicppcomplete吐出“Pattern Not Found”。
我注意到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能够在{{1}上完成}。
我是否在str.
设置let OmniCpp_DefaultNamespaces = ["std", "_GLIBCXX_STD"]
似乎无关紧要。
问题是将.vimrc
声明放在头文件中似乎是一个很大的禁忌,所以我回到原点。
答案 0 :(得分:1)
我最近搬到了Ubuntu 10.04,其中包括ctags 5.8,我不再像STL这样的STL类有这个问题,但是完成仍然不能像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
然后修改生成ctags的.vimrc
文件中的行,如下所示:
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容器集,甚至可以自动修改签入时的头或使用Perl脚本从Subversion存储库签出。
这样你的队友就不需要看到你丑陋的黑客了: - )
答案 1 :(得分:0)
尝试设置此变量:
let OmniCpp_NamespaceSearch=1
如果有效,请不要忘记将其放在.vimrc
配置文件中!