Issue
The following is valid, standard-conforming code from the GCC source code base. It trips the Visual C++ compilers, triggering error C2244. That is a compiler bug that I already reported, but it's unlikely to get solved soon. Too low of an impact they say. Now, I'd be rather miffed if my compiler product choked on a leading open-source compiler codebase, but that's just me.
Is there some workaround or a way to rewrite this to preserve the API while getting it past VS C++?
Getting the function body inside the class declaration works around the issue, but that's a bit of a stylistic nightmare and has about zero chance of upstreaming. So I was hoping for something less drastic.
Error:
(17): error C2244: 'hash_table::traverse_noresize': unable to match function definition to an existing declaration
Self-contained repro case below - also available on Godbolt. No compile flags needed, and AFAIK it trips all releases of 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>();
}
Solution
The problem is that MSVC is resolving the alias hash_table<...>::value_type
early, and then failing to resolve it during member function (template) declaration matching. Manually dealiasing at the definition appears to work:
template<typename Descriptor>
template<typename Argument,
int (*Callback)
(typename Descriptor::value_type *slot,
// ^~~~~~~~~~
Argument argument)>
void hash_table<Descriptor>::traverse_noresize () {}
Demo.
Answered By - ecatmur Answer Checked By - Mary Flores (WPSolving Volunteer)