И G cc, и MSV C верны. Тип 2-го параметра шаблона std::array
определяется как std::size_t
, а способ определения std::size_t
зависит от реализации.
typedef /*implementation-defined*/ size_t;
std::size_t
- это целочисленный тип без знака результата оператора sizeof as well as the sizeof... operator and the alignof operator (since C++11)
.
Ширина бита std::size_t
не меньше 16. (начиная с C ++ 11)
Тогда, когда std::size_t
определено так же, как unsigned int
, код компилируется нормально, в противном случае произойдет сбой; несоответствие типов приводит к сбою вывода аргументов не типового шаблона.
Измените unsigned int
на std::size_t
, тогда код гарантированно будет хорошо скомпилирован любыми приличными компиляторами. Например,
template<typename T> class myClass {
public:
template<std::size_t N> myClass(const std::array<T, N>& elems) { /* do something */ }
};
И о том, почему несоответствие типов приводит к сбою вывода аргумента шаблона нетипичного типа.
(выделение мое)
Если шаблон нетипичного типа Параметр используется в списке параметров, и выводится соответствующий аргумент шаблона, тип аргумента выведенного шаблона (как указано в прилагаемом списке параметров шаблона, то есть ссылки сохраняются) должен соответствовать типу нетипичного параметр шаблона в точности , за исключением того, что cv-квалификаторы отбрасываются и кроме случаев, когда аргумент шаблона выводится из границы массива - в этом случае допускается любой целочисленный тип, даже bool, хотя он всегда становится истинным:
template<int i> class A { };
template<short s> void f(A<s>); // the type of the non-type template param is short
void k1()
{
A<1> a; // the type of the non-type template param of a is int
f(a); // P = A<(short)s>, A = A<(int)1>
// error: deduced non-type template argument does not have the same
// type as its corresponding template argument
f<1>(a); // OK: the template argument is not deduced,
// this calls f<(short)1>(A<(short)1>)
}
template<int&> struct X;
template<int& R> void k2(X<R>&);
int n;
void g(X<n> &x) {
k2(x); // P = X<R>, A = X<n>
// parameter type is int&
// argument type is int& in struct X's template declaration
// OK (with CWG 2091): deduces R to refer to n
}