首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Vim + OmniCppComplete:在STL容器的类成员上完成

Vim + OmniCppComplete:在STL容器的类成员上完成
EN

Stack Overflow用户
提问于 2010-05-16 08:53:56
回答 2查看 2.1K关注 0票数 11

STL容器类成员的完成失败。

完成本地对象(即STL容器)可以很好地工作。

例如,给定以下文件:

代码语言:javascript
复制
// 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  ----- */

我使用以下方法为这两个文件生成了标记:

代码语言:javascript
复制
ctags -R --c++-kinds=+pl --fields=+iaS --extra=+q .

当我在cpp中输入temp.时,我会得到一个string成员函数的列表。但是,如果我输入str.,omnicppcomplete就会发出“模式未找到”。

我注意到,只有当我有temp.声明时,using std::string;完成才能工作。

如何完成对属于STL容器的类成员的工作?

编辑

我发现,如果对标头进行以下修改,对STL容器成员的完成是可行的:

代码语言:javascript
复制
// 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::成员中删除std::名称空间限定符并重新生成标记文件,那么OmniCppComplete就能够在str.上完成。

我是否将let OmniCpp_DefaultNamespaces = ["std", "_GLIBCXX_STD"]设置在.vimrc中似乎并不重要。

问题是,将using声明放入头文件似乎是一个很大的不-不,所以我回到了原点。

EN

回答 2

Stack Overflow用户

发布于 2010-05-23 14:10:11

我最近转到了Ubuntu10.04,其中包括ctag 5.8,我不再对字符串这样的STL类有这个问题,但是补全仍然不能像向量这样的实际容器工作。

这是我以前对ctag 5.7:的回答

虽然这有点麻烦,但我找到了一种解决方案,它不会用using指令污染头文件,并向OmniCppComplete提供完成类成员(即STL容器)所需的一切。

代码语言:javascript
复制
#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文件中的行,它生成ctag,如下所示:

代码语言:javascript
复制
map <C-F12> :!ctags -R --c++-kinds=+pl --fields=+iaS --extra=+q --if0=yes .<CR>

这是怎么回事?当ctags看到--if0=yes选项时,它将接受预处理器指令的#if 0分支,并在tags文件中生成必要的条目:

代码语言:javascript
复制
str omnitest.h  /^    string str;$/;"   m   class:foo   access:private

OmniCppComplete看到了假using std::string;,当它找不到string的定义时,它会在std命名空间中查找并在那里找到它。

在用g++编译时,输出就是我们想要的。这可以通过通过预处理器运行文件来验证:

代码语言:javascript
复制
$ g++ omnitest.cpp -E | less

最后你会看到:

代码语言:javascript
复制
# 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
EN

Stack Overflow用户

发布于 2010-05-18 14:36:16

尝试设置以下变量:

代码语言:javascript
复制
let OmniCpp_NamespaceSearch=1

如果它有效,不要忘记将它放在您的.vimrc配置文件中!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2843107

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档