【问题标题】:C++ template that used to work in old gcc results in 'shadows template parameter' error in clang++用于在旧 gcc 中工作的 C++ 模板在 clang++ 中导致“阴影模板参数”错误
【发布时间】:2014-02-27 00:34:45
【问题描述】:

我在 08 年左右使用 gcc 3.x 编写了这段代码。我现在正在尝试使用 clang 3.4 进行编译,但遇到了一个我不理解的模板错误。这个想法是声明任意维度和精度的固定维度 vec 类型,然后基于这些定义 vecPair 类型。我不明白“a.convert()”中模板类型名 S 的使用如何影响模板参数;它旨在使用参数,而不是重新声明它。任何信息将不胜感激!

typedef unsigned int Uns;

template <typename T>
inline const T& min(const T& a, const T& b) {
  return a <= b ? a : b;
}

template <Uns N, typename T>
struct vec {

  T comp[N];

  template <Uns M, typename S>
  inline vec<M, S> convert() const {
    vec<M, S> converted;
    for (Uns i = 0; i < min(M, N); ++i) converted[i] = comp[i];
    for (Uns i = N; i < M; ++i) converted[i] = 0;
    return converted;
  }
};

template <Uns N, typename T>
struct vecPair {

  vec<N, T> a;
  vec<N, T> b;

  inline vecPair(const vec<N, T>& _a, const vec<N, T>& _b) : a(_a), b(_b) {}

  template <Uns M, typename S>
  inline vecPair<M, S> convert() const {
    vec<M, S> ca = a.convert<M, S>();
    vec<M, S> cb = b.convert<M, S>();
    return vecPair<M, S>(ca, cb);
  }
};

clang 3.4 给出以下输出:

$ clang++ -fsyntax-only vec-bug.cpp 
vec-bug.cpp:30:33: error: declaration of 'S' shadows template parameter
    vec<M, S> ca = a.convert<M, S>();
                                ^
vec-bug.cpp:28:29: note: template parameter is declared here
  template <Uns M, typename S>
                            ^
vec-bug.cpp:30:34: error: expected ';' at end of declaration
    vec<M, S> ca = a.convert<M, S>();
                                 ^
                                 ;
vec-bug.cpp:31:12: error: template argument for template type parameter must be a type
    vec<M, S> cb = b.convert<M, S>();
           ^
vec-bug.cpp:11:27: note: template parameter is declared here
template <Uns N, typename T>
                          ^
...

【问题讨论】:

  • 好吧,我复制了。 G++VC++ 不给出警告或错误,clang++ 给出列出的警告。我被难住了。
  • 我认为这是一个 SSCCE:ideone.com/bieydI。看来 clang 正在将其解析为 a.convert&lt;M 和一个(无法解析的)S&gt;(),由逗号运算符分隔。现在我不再确定 clang 是错的。可能是 G++ 和 VC++ 在技术上是错误的,不确定。

标签: c++ templates clang++


【解决方案1】:

这似乎有效:

vec<M, S> ca = a.template convert<M, S>();
vec<M, S> cb = b.template convert<M, S>();

我认为ab 具有依赖类型,因此您需要明确convert 是一个模板。我不确定为什么 GCC 不介意。

更新:这似乎是known GCC bug.

【讨论】:

  • 我从来没有完全弄清楚什么时候需要像这样需要template,现在我不确定哪个编译器是错误的。
  • @MooingDuck:看起来有点直截了当:你不知道a的类型是什么,所以你不知道它是否有一个名为convert的成员,以及是否该成员是一个值、一个类型或一个模板。 (请记住,vec 可以专门化。)
  • @MooingDuck:我刚刚检查了 14.6.2.2 中的完整规则,但我并不完全清楚“未知专业化”在这种情况下的含义。不过,我倾向于 Clang 在这方面是正确的。 (尤其是 14.6.2.2/5 似乎很好地描述了目前的情况。)
猜你喜欢
  • 2016-06-15
  • 1970-01-01
  • 2014-01-19
  • 1970-01-01
  • 2012-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-27
相关资源
最近更新 更多