I'm trying to understand template specialization in modern C++. The code makes no sense, it is only a proof of concept. (Or rather, a disproof until now.)
template<char... cs> struct xyz
{
static size_t const data = 0;
};
template<char c0, char c1, char c2, char... cs> struct xyz
{
static size_t const data = 1;
};
auto x1 = xyz<'a'>::data;
auto x2 = xyz<'a', 'b', 'c', 'd'>::data;
The idea is to have a template that takes any number of characters, and to specialize it with a template that takes at least three characters. I would expect x1==1, and x2==2.
When I compile this in MSVC2022, I get the following error messages at the line marked with [2]:
error C3855: 'xyz': template parameter 'cs' is incompatible with the declaration
error C2977: 'xyz': too many template arguments
message : see declaration of 'xyz'
The third message points to line [1].
In contrast, when I do the same with a function template, results are different:
template<char... cs>size_t zyx()
{
return 0;
}
template<char c0, char c1, char c2, char... cs> size_t zyx()
{
return 1;
};
auto z1 = zyx<'a'>();
auto z2 = zyx<'a', 'b', 'c', 'd'>();
Again, I would assume z1==1, and z2==2.
This time, the template definitions compile error-free, but when I try to use the function, the error messages are:
error C2668: 'zyx': ambiguous call to overloaded function
message : could be 'size_t zyx<97,98,99,100>(void)'
message : or 'size_t zyx<97,98,99,100>(void)'
message : while trying to match the argument list '()'
These messages point to the lines [13], [12], [11], and [13] again.
What I have tried:
I tried with "/std:c++latest" as well as with "/std:c++20", with identical results.
Have I run into a compiler bug, or is it my wrong thinking?
Edit: When I use compiler explorer, it fails with every compiler I try. I conclude it must be the code, not the compiler.