Действительно, параметры шаблона, которые вы определили, - это параметры не-типа, в отличие от двух других вариантов шаблонов: параметры типа и параметры шаблона.
Однако они все еще являются параметрами шаблона, и вы получите совершенно новый тип данных для каждого отдельного набора аргументов шаблона. Например, foo<3,'a'>
- это другой тип данных от foo<4,'a'>
, который снова отличается от foo<3,'b'>
и так далее.
Следовательно, статические элементы отдельно выделяются и инициализируются для каждого выбора аргументов шаблона.
В этом отношении параметры непигового типа, параметры типа и параметры шаблона работают одинаково.
Для справки, от стандарта (C++ 11):
(§ 14.7/6) Каждый шаблон класса специализации реализованным из шаблона имеет свою собственную копию любых статических членов. [Пример:
template<class T> class X {
static T s;
};
template<class T> T X<T>::s = 0;
X<int> aa;
X<char*> bb;
X<int>
имеет статический член s
типа int
и X<char*>
имеет статический элемент s
типа char*
. - конец примера]
Пример, приведенный выше, относится к параметрам типа, но раздел 14.7/6 является частью общего обсуждения шаблонов. Более широкий контекст дает понять, что это выполняется для шаблонов, которые используют параметры не-типа (или комбинацию параметров типа, не-типа и шаблона).
Существует также раздел, посвященный типа эквивалентности для шаблона конкретизации, что объясняет при каких обстоятельствах шаблон инстанциацию с параметрами не типа рассматриваются как равные (соответствующие части, подчеркнутых мной):
(§14/1) Два идентификатора шаблона относятся к одному и тому же классу или функции, если
- их имена шаблонов, идентификаторы-операторы-функции или литеральные-идентификаторы-операторы ссылаются на один и тот же шаблон и
- их соответствующие шаблоны-аргументы типа одного типа и
- их соответствующие аргументы типа non-type интегрального или перечисляемого типа имеют одинаковые значения и
- их соответствующие непиготные шаблонные аргументы типа указателя относятся к одному и тому же внешнему объекту или функции или оба значения нулевого указателя и
- их соответствующие non-type template-arguments типа pointer-to-member относятся к одному и тому же члену класса или являются значениями указателя нулевого элемента и
- их соответствующие непиготные шаблонные аргументы ссылочного типа относятся к одному и тому же внешнему объекту или функции и
- их соответствующие шаблонные шаблоны шаблонов относятся к одному и тому же шаблону.
В контексте это означает, что два экземпляра одного шаблона класса представляют собой два разных типа данных, даже если они отличаются значением только одного параметра, отличного от типа.
Последний. ... – jxh
На ваш ответ ответит этот вопрос. Он создает новый класс для каждого другого аргумента. – Rapptz
Что такое downvotes? Достойный вопрос, на мой взгляд. Мой компилятор показывает struct foo как тип foo, на мой взгляд, все такие типы одинаковы и должны делиться статическим членом. –
Twifty