2013-07-17 2 views
0

Существует аналогичный вопрос here, но он связан с шаблонами с ключевым словом typename.Статический член шаблона

Учитывая шаблон:

template < int X, char Y > 
struct foo 
{ 
    char myArray[ X <= 0 ? 1 : X ]; 
    static const char Z = Y; 
} 

бы, что статический член, разделяется между всеми экземплярами foo или будет составитель видеть, что шаблон был вызван с различными аргументами и создать новый тип?

+0

Последний. ... – jxh

+0

На ваш ответ ответит этот вопрос. Он создает новый класс для каждого другого аргумента. – Rapptz

+0

Что такое downvotes? Достойный вопрос, на мой взгляд. Мой компилятор показывает struct foo как тип foo , на мой взгляд, все такие типы одинаковы и должны делиться статическим членом. – Twifty

ответ

3

Член статической константы, назначенный там, изменяется в зависимости от значения, которое передается параметром шаблона. Сократить его на что-то вроде этого:

template<int X> 
struct foo { 
    static const int value = X; 
}; 

Вы не ожидали бы foo<10>::value равным foo<11>::value бы вы? Это обычно используется в мета-программировании шаблонов, потому что значение этой статической константы зависит от параметра шаблона.

+0

Спасибо, что он делает это очень ясно. – Twifty

3

Действительно, параметры шаблона, которые вы определили, - это параметры не-типа, в отличие от двух других вариантов шаблонов: параметры типа и параметры шаблона.

Однако они все еще являются параметрами шаблона, и вы получите совершенно новый тип данных для каждого отдельного набора аргументов шаблона. Например, 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 относятся к одному и тому же члену класса или являются значениями указателя нулевого элемента и
- их соответствующие непиготные шаблонные аргументы ссылочного типа относятся к одному и тому же внешнему объекту или функции и
- их соответствующие шаблонные шаблоны шаблонов относятся к одному и тому же шаблону.

В контексте это означает, что два экземпляра одного шаблона класса представляют собой два разных типа данных, даже если они отличаются значением только одного параметра, отличного от типа.

+0

Спасибо, ответит на мой вопрос напрямую. – Twifty

Смежные вопросы