提问人:Kuba hasn't forgotten Monica 提问时间:11/15/2023 最后编辑:Kuba hasn't forgotten Monica 更新时间:11/15/2023 访问量:78
是否有任何明显的方法可以重写此代码以解决触发无效 C2244 错误的编译器错误?
Is there any obvious way to rewrite this code to work around a compiler bug triggering invalid C2244 error?
问:
以下是 GCC 源代码库中符合标准的有效代码。它使Visual C++编译器跳闸,触发错误C2244。这是我已经报告过的编译器错误,但它不太可能很快得到解决。他们说影响太小了。现在,如果我的编译器产品在领先的开源编译器代码库上窒息,我会很生气,但这只是我。
是否有一些解决方法或方法可以重写它以保留 API,同时让它通过 VS C++?
在类声明中获取函数体可以解决这个问题,但这有点像风格上的噩梦,并且上游的可能性几乎为零。所以我希望能有不那么激烈的事情。
错误:
(17):错误 C2244:“hash_table::traverse_noresize”:无法将函数定义与现有声明匹配
下面的独立复制案例 - 也可在 Godbolt 上使用。不需要编译标志,AFAIK 它会绊倒 VS 2022 的所有版本。
// minimized excerpt from gcc/hash_table.h
template <class Descriptor> class hash_table
{
using value_type = typename Descriptor::value_type;
public:
template <int (*Callback)(value_type *)> void traverse_noresize ();
};
template<class Descriptor>
template<int (*Callback) (typename hash_table<Descriptor>::value_type *)>
void hash_table<Descriptor>::traverse_noresize() {}
// Error C2244 in line above. Apparently, this definition doesn't match the declaration
// in the class body.
struct D { using value_type = int; };
int C(int *slot) { return {}; }
void test()
{
hash_table<D> ht;
ht.traverse_noresize<C>();
}
答:
4赞
ecatmur
11/15/2023
#1
问题是 MSVC 提前解析别名,然后在成员函数 (模板) 声明匹配期间无法解析它。在定义处手动消除锯齿似乎有效:hash_table<...>::value_type
template<typename Descriptor>
template<typename Argument,
int (*Callback)
(typename Descriptor::value_type *slot,
// ^~~~~~~~~~
Argument argument)>
void hash_table<Descriptor>::traverse_noresize () {}
演示。
评论
0赞
Kuba hasn't forgotten Monica
11/15/2023
棒!谢谢!
0赞
Thomas Weller
11/15/2023
即使 Descriptor::value_type 是私有的,也有效?因为。。。private 仅用于动态多态性,而不是静态多态性?
0赞
Kuba hasn't forgotten Monica
11/15/2023
@ThomasWeller 它似乎适用于所有主要的编译器:)
1赞
Thomas Weller
11/15/2023
啊,不,我的错。该方法是类的一部分,因此可以看到私有内容。没事的。
评论