gpt4 book ai didi

c++ - 为什么 MSVC 编译这个模板函数失败?

转载 作者:IT老高 更新时间:2023-10-28 23:21:32 26 4
gpt4 key购买 nike

我在将一些代码移植到 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 给了我这个错误:

error C2893: Failed to specialize function template 'S::val> foo(T)'

所以我的问题:

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

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

最佳答案

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

有趣的是,当你改变 S< E e >取而代之的是整数,它可以工作。考虑这个示例,与您的示例相同,但命名有所不同:

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<T>::val

在哪里 val是任何一种枚举。我有 99% 的把握这是编译器本身的缺陷。这似乎是完全格式良好的 C++,所以我不能说 GCC 通过让原始代码片段工作而做错了什么或扩展。因此,我能收集到的最好的结果是,MSVC 与同行相比,在编译器的鲁棒性方面再次不足。

您可以在此处停止阅读,因为现在我要花一点时间来吐槽一下 MSVC 编译器。

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

关于c++ - 为什么 MSVC 编译这个模板函数失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15466594/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com