【问题标题】:Why does MSVC fail to compile this template function?为什么 MSVC 编译这个模板函数失败?
【发布时间】:2013-03-06 04:27:17
【问题描述】:

我在将一些代码移植到 MSVC 时遇到了问题,这让我很困惑。据我所知,代码应该是合法的,Clang编译就好了。

我已将范围缩小到以下几点:

enum E {
    x
};

template <typename T>
struct traits {
    static const E val = x;
};

template <E e>
struct S {
    S(){};
};

template <typename T>
S<traits<T>::val> foo(T t);

int main() {
    char c = 0;
    foo(c);
}

请注意,编译后,代码预计会产生链接器错误(我删除了函数 foo 的定义以保持样本最小化),但它应该编译干净据我所知。

但是,MSVC 给了我这个错误:

错误 C2893:无法专门化函数模板 'S::val> foo(T)'

所以我的问题:

  • MSVC 在拒绝代码方面是否正确? (如果是,为什么?)
  • 如果没有,谁能缩小它做错的范围?例如,这是他们根本没有实现的语言功能(例如模板的两阶段名称查找),还是在他们声称支持的功能的实现中“只是”一个简单的错误?

我已经在 VC++ 2010 和 2012 上重现了这个问题。

【问题讨论】:

  • @BoPersson:似乎与我无关。除了这里的错误,我想不出其他任何东西。顺便说一句,它在 GCC 4.7.2 上按预期工作
  • 此外,如果将enum 替换为int,则错误消失。好像是enums相关的bug
  • 当然这是一个错误。 The compiler failed to do this or that,谁在乎?我需要知道我的程序违反了哪种语言规则,如果这或多或少晦涩难懂,请引用标准。一些编译器编写者根本不知道。尽管如此,我还是会尝试实例化traits&lt;char&gt;S&lt;traits&lt;char&gt;::val&gt;,只是为了看看编译器的反应。
  • @n.m.:没有人说“这是一个错误”就足够了。我们只是在写 cmets。另外,由于我认为这是一个编译器错误,我相信该程序没有违反任何规则。

标签: c++ templates visual-c++


【解决方案1】:

在自己运行了一些测试之后,这似乎是 MSVC 中的编译器错误。虽然它适用于 GCC,但当您尝试在 S&lt; E e &gt; 返回的模板参数中使用 traits&lt;T&gt;::val 时,MSVC 会给出神秘且无用的编译器错误(与您的问题中的错误相同)。

有趣的是,当您将 S&lt; E e &gt; 更改为取整数时,它会起作用。考虑这个示例,与您的示例相同,但命名有所不同:

enum E {
    x
};

template <typename T>
struct traits {
    static const E val = x;
};

template <E e>
struct S {
    S(){};
};

template <typename T>
S< traits<T>::val > tricky(T t) {
    return S< traits<T>::val > ();
};

int main() {
    char thiskidwhowalksaround = 0;
    S<x> s = tricky( thiskidwhowalksaround );
}

现在,让我们改变一件事

template <int e> // int instead of E
struct S {
    S(){};
};

然后程序为我完美地编译(链接和运行)。如果你也恢复到原来的,然后直接传入一个E的值,比如:

template <typename T>
S< x > tricky(T t) { 
// ^ here
    return S< x > (); // <-- here
};

然后程序编译文件。 MSVC 在尝试执行以下操作时会遇到麻烦:

traits&lt;T&gt;::val

其中val 是任何类型的枚举。我 99% 确定这是编译器本身的缺陷。这似乎是完全格式良好的 C++,所以我不能说 GCC 通过让原始代码 sn-p 工作而做错了什么或扩展。因此,我能收集到的最好结果是,MSVC 与其他同类产品相比,在编译器的鲁棒性方面再次不足。

你可以停止阅读这里,因为现在我要花一点时间来抱怨 MSVC 编译器。

begin&lt;rant&gt; 不是 VC++ 团队不好或 C++ 不好,而是从我收集到的编译器团队和微软的标准库团队 - 在撰写本文时 - 很小 与其他部门相比。令我恼火的是,如此基础和重要的语言以及 MS 行业核心的一部分,其人力相对较少,以至于它无法跟上我在短暂的一生中发现的世界上发展最慢的标准之一。我当然不是在抨击在 VC++ 团队中工作的人,但我对为什么没有更多人致力于使 C++ 不仅达到速度而且使编译器更好地工作并且与其他人一样好,我深感困惑产品领域。 end&lt;rant&gt;

【讨论】:

  • 这确实是一个编译器错误。我在Connect 上报告了它,他们只是表示它将在“Visual C++ 的下一个版本中”修复它......无论何时
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-29
  • 1970-01-01
  • 2011-04-07
  • 1970-01-01
相关资源
最近更新 更多