【问题标题】:How to enable completion of C++ template classes in vim using YouCompleteMe如何使用 YouCompleteMe 在 vi​​m 中启用 C++ 模板类的完成
【发布时间】:2014-10-09 03:43:02
【问题描述】:

在使用 vim 插件 YouCompleteMe 完成 C++ 代码时,我偶然发现了一个问题。 使用嵌套模板类会阻止完成正常工作。

考虑以下示例来重现该行为:

#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"
}

“some_bars”的代码完成根本无法正常工作,而“one_bar”的行为符合预期。

我如何才能完成此代码的工作?这个问题是否与设置有关并且应该实际工作或者它是 YCM 中的错误?

我的系统是基于 debian jessie/sid,vim 版本 7.4,来自 GitHub 的 YCM 最新版本。

编辑: YCMs bug tracker 中报告了类似的问题: https://github.com/Valloric/YouCompleteMe/issues/243 https://github.com/Valloric/YouCompleteMe/issues/530

似乎是 clang 而不是 YCM 中的错误。有人可以确认吗?

编辑2: 我在 YCM 问题跟踪器中打开了另一个问题。 https://github.com/Valloric/YouCompleteMe/issues/1170

目的是获得更多关于clang中的错误究竟是什么的信息,最后在clang问题跟踪器中进行错误报告。

编辑3: 我遵循了 RedX 提出的程序,并在 clang 中输入了我的代码以完成。 Clang 没有为代码中讨论的位置提供任何建议。 这显然是 YCM 无法在 vim 中提出建议的原因,与 YCM 或 vim 无关。

clang 问题跟踪器中的错误报告已提交: http://llvm.org/bugs/show_bug.cgi?id=20973

【问题讨论】:

  • 这个问题在 SO 上得到令人信服的答案的机会接近于 0。YCM 只是 clang 的一个 hacky 前端,所以你为什么不直接尝试clang's issue tracker
  • Valloric 似乎已经在您发布的问题中确认这是一个错误/clang 不支持。
  • @FDinoff :赏金用于解释问题的确切位置以及如何解决。
  • @romainl :我对clang一无所知,所以我不知道从哪里开始。因此,赏金:我需要有人解释 clang 中的问题在哪里,并可能在那里打开一个问题。 YCM 对很多人来说是一个很棒的工具,这是一个让它变得更好的机会。
  • 尝试将这个 sn-p 喂给 clang 并要求它为您提供补全。请参阅this post,了解如何从命令行/std 中执行此操作。然后也许您可以创建一个可复制的示例。

标签: c++ templates vim clang code-completion


【解决方案1】:

我认为,根据 C++ 的规则,在这种情况下你无法完成。

如果不知道 T 的类型,我们不知道 std::vector&lt;T&gt; 会有哪些方法,因为 C++ 中模板的每个实例化都可以有不同的方法。

【讨论】:

  • 在此处显示的代码中,即使不知道 T 类型,也清楚地知道所有完成。它不是 std::vector 而是 std::vector: :bar>.
【解决方案2】:

正如上面提到的@Chris Jefferson,理论上是不可能的。 此评论未考虑模板专业化

在此处显示的代码中,即使不知道类型 T,所有补全都是清楚的。它不是 std::vector 而是 std::vector<:bar>

当我试图为模板编写专业化而不扣除模板时,这发生在一个非常不同的背景下。我将提供我的例子来说明情况。因此,假设您有一个枚举器,并且您有一个 meta_info 类,该类定义了模板所采用的枚举器的大小:

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

好的,这很好用,但是如果您尝试在嵌套在模板类中的枚举器中做同样的事情会发生什么?

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;
}

这不会编译,因为其他人(代码的另一部分)可能会用另一个特化更改 e。即使在编译的第一次通过时,编译器也没有正式的方法可以知道特化是否更改了类型.请记住,大多数时候自动完成工具只使用包含路径来查找建议,这是不可能的。所以将来我希望在 ycm 中看到类似非正式实例化like VS has done

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-09
    • 1970-01-01
    • 1970-01-01
    • 2013-09-19
    • 1970-01-01
    • 2020-05-23
    相关资源
    最近更新 更多