gpt4 book ai didi

c++ - Vim + OmniCppComplete : Completing on Class Members which are STL containers

转载 作者:IT王子 更新时间:2023-10-29 00:01:58 25 4
gpt4 key购买 nike

作为 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 会吐出“未找到模式”。

我注意到 temp. 完成只有在我有 using std::string; 声明时才有效。

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

编辑

我发现,如果我对 header 进行以下修改,对作为 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;,然后从 string str; 中删除 std:: namespace 限定符成员并重新生成标签文件,然后 OmniCppComplete 就能够完成 str..

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

问题是在头文件中放置 using 声明似乎是一个很大的禁忌,所以我回到原点。

最佳答案

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

这是我对 ctags 5.7 的旧答案:

虽然有点 hack,但我找到了一个解决方案,它不会使用 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 分支并在标签文件:

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 脚本 checkin 或 checkout Subversion 存储库时自动修改 header 。

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

关于c++ - Vim + OmniCppComplete : Completing on Class Members which are STL containers,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2843107/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com