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

时间:2014-08-15 11:45:27

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

当使用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"
}

&#34; some_bars&#34;的代码完成&#34; one_bar&#34;表现得像预期的那样。

如何完成此代码的完成?这个问题是否与设置有关并且实际应该有效,还是YCM中的错误?

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

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

似乎是clang而不是YCM中的错误。有人可以证实这一点吗?

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

目的是获取有关clang中的错误信息的更多信息,最后在clang问题跟踪器中进行错误报告。

EDIT3: 我按照RedX的建议程序,在clang中输入我的代码以获得完成。 Clang没有为代码中讨论的位置提供任何建议。 这显然是YCM未能在vim中提出建议的原因,它与YCM或vim无关。

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

2 个答案:

答案 0 :(得分:2)

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

在不了解T类型的情况下,我们不知道std::vector<T>会有什么方法,因为C ++中每个模板的实例可以有不同的方法。

答案 1 :(得分:0)

正如@Chris Jefferson所述,从理论上讲是不可能的。 此评论未考虑帐户模板的专业化

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

这是在非常不同的情况下发生的,当时我正尝试为模板编写专门化的内容而不扣除模板。我将提供示例以说明情况。因此,假设您有一个枚举器,并且您有一个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并使用另一种特殊化。即使是在初次通过时,编译器也没有正式的方法来知道特殊化是否改变了类型的编译。请记住,大多数情况下,自动完成工具仅使用include路径来查找建议,这是不可能的。因此,将来我希望在ycm中看到类似非正式实例化的like VS has done