
"David Abrahams" <dave@boost-consulting.com> wrote
In the first specialization, T is int[20]. This is due to the strange way in which cv-qualification "commutes" with array bounds:
typedef int a20[20]; typedef a20 const ca20i; // an const array of 20 ints
typedef int const a20ci[20]; // an array of 20 const ints. template <class T> struct X; template <class T> struct X<T const> {}; // template <class T, int N> struct X<T[N]> {}; -- uncomment for ambiguity X<ca20i> a; // the same type X<a20ci> b;
Or, in other words, by definition, "array of const/volatile T" is the same as "const/volatile array of T" (which basically causes the ambiguity)? This looks like unique quality of arrays and we should not run into it in any other contexts, should we?
Here's how you check whether they're equally specialized:
synthesize unique types and values for T and N in each specialization:
template <class T> struct X<T const> {}; // T = struct Foo {}; template <class T, int N> struct X<T[N]> {}; // T = struct Bar {};, N = Q
can "Foo const" match "T[N]"? No. can "Bar[Q]" match "T const"? No.
Therefore: they're equally specialized.
And the easiest way to resolve this particular case would be to provide the third specialization: template <class T, int N> struct X<const T[N]> {}; // T = struct Foo{};, N = Q To handle volatiles (I am not doing this right now), I would just have to add another two: template <class T, int N> struct X<volatile T[N]> {}; template <class T, int N> struct X<const volatile T[N]> {}; Am I getting this correctly? Arkadiy