简体   繁体   English

如何使用 YouCompleteMe 在 vi​​m 中启用 C++ 模板类的完成

[英]How to enable completion of C++ template classes in vim using YouCompleteMe

When using the vim plugin YouCompleteMe for C++ code completion I stumbled over an issue.当使用 vim 插件 YouCompleteMe 来完成 C++ 代码时,我偶然发现了一个问题。 Using nested template classes stops the completion to work properly.使用嵌套模板类会阻止完成正常工作。

Consider the following example to reproduce the behaviour:考虑以下示例来重现该行为:

#include <vector>

template<class T>
class foo {
  public:
  void Init();

  private:
  struct bar {
    int foobar;
  };
  bar one_bar;
  std::vector<foo<T>::bar> some_bars;
};

template<class T>
void foo<T>::Init(){
  one_bar.foobar = 0; // completion as expected
  some_bars.at(0).foobar = 0; // no completion neither for "at" nor for "foobar"
}

The code completion for "some_bars" is not working at all while "one_bar" behaves as expected. “some_bars”的代码完成根本不起作用,而“one_bar”的行为符合预期。

How can I get completion working for this code?我怎样才能完成此代码的工作? Is this issue related to the setup and should actually work or is it a bug in YCM?这个问题是否与设置有关并且应该实际起作用还是YCM中的错误?

My system is debian jessie/sid based, vim version 7.4, YCM latest version from GitHub.我的系统基于 debian jessie/sid,vim 版本 7.4,来自 GitHub 的 YCM 最新版本。

Edit: There are similar issues reported in YCMs bug tracker: https://github.com/Valloric/YouCompleteMe/issues/243 https://github.com/Valloric/YouCompleteMe/issues/530编辑:YCM 错误跟踪器中报告了类似的问题: https : //github.com/Valloric/YouCompleteMe/issues/243 https://github.com/Valloric/YouCompleteMe/issues/530

Seems to be a bug in clang rather than in YCM.似乎是 clang 而不是 YCM 中的错误。 Can someone confirm this?有人可以证实这一点吗?

Edit2: I opened another issue in the YCM issue tracker. Edit2:我在 YCM 问题跟踪器中打开了另一个问题。 https://github.com/Valloric/YouCompleteMe/issues/1170 https://github.com/Valloric/YouCompleteMe/issues/1170

The intention is to get more information on what the bug in clang exactly is and finally to make a bug report in the clang issue tracker.目的是获得有关 clang 中错误究竟是什么的更多信息,并最终在 clang 问题跟踪器中进行错误报告。

Edit3: I followed the proposed procedure from RedX and fed my code in clang to get completions. Edit3:我遵循了 RedX 提出的程序,并在 clang 中输入了我的代码以获得完成。 Clang does not provide any suggestions for the discussed positions in the code. Clang 不对代码中讨论的位置提供任何建议。 This clearly is the reason why YCM fails to make suggestions in vim and it has nothing to do with YCM or vim.这显然是YCM无法在vim中提出建议的原因,它与YCM或vim无关。

A bug report in the clang issue tracker has been filed: http://llvm.org/bugs/show_bug.cgi?id=20973已提交 clang 问题跟踪器中的错误报告: http : //llvm.org/bugs/show_bug.cgi?id=20973

I think, under the rules of C++, you cannot get completion in this case.我认为,根据 C++ 的规则,在这种情况下您无法完成。

Without knowledge of the type T , we don't know what methods std::vector<T> will have, as each instansiation of a template in C++ can have different methods.如果不了解T类型,我们就不知道std::vector<T>将具有哪些方法,因为 C++ 中模板的每个实例都可以具有不同的方法。

As @Chris Jefferson mentioned above it is theoretically impossible .正如@Chris Jefferson 上面提到的那样,理论上是不可能的。 This comment doesn't take in account template specializations此评论不考虑模板专业化

In the code shown here, all completions are clearly known, even without knowing the type T. It is not a std::vector but a std::vector<foo::bar>在这里显示的代码中,即使不知道 T 类型,所有补全都清楚地知道。它不是 std::vector 而是 std::vector<foo::bar>

This occurred to me in a very different context while I was trying to write a specialization for a template without deducting a template.I will provide my example to make the situation clear.当我试图在不扣除模板的情况下为模板编写专业化时,我在一个非常不同的上下文中发生了这种情况。我将提供我的例子来说明情况。 So lets say you have an enumerator and you have a meta_info class that defines a size for an enumerator it takes by template so :因此,假设您有一个枚举器,并且您有一个 meta_info 类,该类定义了模板采用的枚举器的大小,因此:

enum class e{a,b};
template <class Enum>
struct meta_info;
template<>
meta_info<e>{
    static constexpr size_t s=2;
}

Ok this works and it is nice to have but what happens if you try to do the same thing in an enumerator nested in a template class?好的,这很有效,而且很好,但是如果您尝试在嵌套在模板类中的枚举器中执行相同的操作,会发生什么情况?

template <class Tag>
struct str{
   enum class e{a,b};
}
template <class Enum>
struct meta_info;
template<T>
meta_info<str<T>::e>{
    static constexpr size_t s=2;
}

This doesn't compile as someone else(another part of the code) might change e with another specialization.There is no formal way for a compiler to know if a specialization changes a type even at the first passes of compilation.这不会编译,因为其他人(代码的另一部分)可能会用另一个特化改变e 。即使在编译的第一遍,编译器也没有正式的方法来知道特化是否改变了类型。 Having in mind that auto-complete tools most of the times just use the includes paths to find a suggestion this would be impossible.请记住,大多数时候自动完成工具只是使用包含路径来查找建议,这是不可能的。 So in the future I would like to see in ycm something like an informal instantiation like VS has done因此,将来我希望在 ycm 中看到类似 VS 所做的非正式实例化

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM