C++ Vim+;OmniCppComplete:在STL容器类成员上完成
STL容器类成员的完成失败 完成本地对象(STL容器)可以很好地工作 例如,给定以下文件:C++ Vim+;OmniCppComplete:在STL容器类成员上完成,c++,linux,vim,ctags,omnicomplete,C++,Linux,Vim,Ctags,Omnicomplete,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" u
// 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 ----- */
当我在cpp中键入temp.
时,我会得到一个string
成员函数的列表。但如果我键入str.
omnicpmplete,则会弹出“找不到模式”
我注意到,只有当我使用std::string时,temp.
完成才有效代码>声明
我如何完成对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;
};
//foo.h
#包括
使用std::string;
福班{
公众:
空集_str(常量字符串&);
字符串get_str_reverse(void);
私人:
字符串str;
};
基本上,如果我使用std::string添加
然后从字符串str中删除std::
名称空间限定符代码>成员并重新生成标记文件,然后OmnicpComplete可以在str.
上完成
我是否在.vimrc
中设置了让OmniCpp\u DefaultNamespaces=[“std”,“\u GLIBCXX\u std”]
似乎并不重要
问题是,在头文件中使用声明似乎是一个很大的禁忌,因此我回到了原点。尝试设置此变量:
let OmniCpp_NamespaceSearch=1
如果它能工作,别忘了把它放在.vimrc
配置文件中 我最近搬到了Ubuntu 10.04,其中包括ctags 5.8,我不再有像string这样的STL类的问题,但是完成仍然不能工作像vector这样的实际容器
这是我对ctags 5.7的旧答案:
虽然这有点像黑客,但我已经找到了一种解决方案,它不会使用
指令污染头文件,并提供OmnicpComplete完成类成员(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
看到--if0=yes
选项时,它将采用预处理器指令的#if 0
分支,并在标记
文件中生成必要的条目:
str omnitest.h /^ string str;$/;" m class:foo access:private
OmniCppComplete使用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存储库时自动修改头
这样,你的队友就不需要看到你丑陋的黑客:-)有趣的是:我试过你的测试,对我来说正好相反!str工作,temp不工作。。。顺便问一下,您使用的是哪个版本的ctags?如果我使用的话,实际上temp也可以工作:让OmniCpp_DefaultNamespaces=[“std”]
@Uncleziv:我在Ubuntu 8.04上使用的是ctags 5.7。我发现是否设置了默认的_名称空间似乎并不重要。请参阅我上面的编辑。我认为建议使用ctags 5.8,尝试编译它或从以后的Ubuntus获得一个包(不应该有任何令人讨厌的依赖)。我已经打开了它,它没有任何区别。如果您感兴趣,我找到了一个解决方案。嗯。。。这真是一个可怕的黑客行为!:)我经常使用#if 0来注释内容,所以我不会使用那个特定的定义。除此之外,我很高兴你找到了一个适合你的解决方案,但我仍然想知道为什么我不能复制你的错误。。。如果我对您的环境中可能出现的问题有其他想法,我会让您知道:)
$ 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);
}