11

作为 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声明放在头文件中似乎是一个很大的禁忌,所以我又回到了原点。

4

2 回答 2

1

我最近搬到了 Ubuntu 10.04,其中包括 ctags 5.8,我不再遇到像字符串这样的 STL 类的问题,但是完成仍然不能工作像向量这样的实际容器。

这是我对 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 容器,甚至可以在使用 Perl 脚本从 Subversion 存储库签入或签出时自动修改标头。

这样你的队友就不需要看到你丑陋的黑客:-)

于 2010-05-23T14:10:11.257 回答
0

Try setting this variable:

let OmniCpp_NamespaceSearch=1

If it works, don't forget to put it in your .vimrc configuration file!

于 2010-05-18T14:36:16.107 回答