Вы можете положиться на это. ODR (одно определение правила) говорит в 3.2/5
в стандарте, где D
обозначает шаблон нестатической функции (рукописный шрифт мной)
Если D является шаблоном и определяется более чем в одной единице перевода, то последние четыре требования из приведенного выше списка должны применяться к именам из области действия шаблона, используемой в определении шаблона (14.6.3), а также к зависимым именам в момент создания (14.6.2). Если определения D удовлетворяют всем этим требованиям, то программа должна вести себя так, как если бы было одно определение D. Если определения D не удовлетворяют этим требованиям, то поведение не определено.
Из последних четырех требований два наиболее важных примерно равны
- каждое определение D должно состоять из одинаковой последовательности токенов
- имена в каждом определении должны относиться к одним и тем же вещам («сущностям»)
Редактировать
Я полагаю, что одного этого недостаточно, чтобы гарантировать, что ваши статические переменные в разных экземплярах одинаковы. Вышеуказанное гарантирует только то, что множественные определения шаблона действительны. Это не говорит что-то о специализациях, полученных из этого.
Именно здесь linkage включается. Если имя специализации шаблона функции (которая является функцией) имеет внешнюю связь (3.5/4
), то имя, относящееся к такой специализации, относится к та же функция. Для шаблона, который был объявлен статическим, функции, созданные из него, имеют внутреннюю связь из-за
Объекты, созданные из шаблона с внутренней связью, отличаются от всех объектов, созданных в других единицах перевода. -- 14/4
Имя, имеющее область пространства имен (3.3.6), имеет внутреннюю связь, если это имя [...] объекта, ссылки, функции или шаблона функции, которые явно объявлены статическими -- 3.5/3
Если шаблон функции не был объявлен с использованием static, то он имеет внешнюю связь (что, кстати, также является причиной того, что мы вообще должны следовать ODR. В противном случае D
не будет определяться множественно совсем!). Это может быть получено из 14/4
(вместе с 3.5/3
)
Шаблон функции, не являющейся членом, может иметь внутреннюю связь; любое другое имя шаблона должно иметь внешнюю связь. -- 14/4
.
Наконец, мы приходим к выводу, что специализация шаблона функции, сгенерированная из шаблона функции с внешней связью, сама имеет внешнюю связь на 3.5/4
:
Имя, имеющее область имен, имеет внешнюю связь, если это имя [...] функции, если оно не имеет внутренней связи -- 3.5/4
И когда это имеет внутреннюю связь, было объяснено 3.5/3
для функций, предоставляемых явными специализациями, и 14/4
для сгенерированных специализаций (создания шаблона). Поскольку имя вашего шаблона имеет внешнюю связь, все ваши специализации имеют внешнюю связь: если вы используете их имя (incAndShow<T>
) из разных единиц перевода, они будут ссылаться на одни и те же функции, что означает, что ваши статические объекты будут одинаковыми в каждом случае ,