В качестве примера рассмотрим этот заголовок:
#include <iostream>
template<bool = true>
struct A {
A() {
static int x;
std::cout << &x << "\n";
}
};
static A<> a;
Что, если бы у меня было два разных файла C ++, включая этот файл — гарантированно ли он напечатал бы один и тот же адрес дважды? Еще важнее, если x
был ли объект другого типа с нетривиальным конструктором, будет ли гарантированно выполняться только один раз?
Стандарт [C ++ 11 14.8 / 2] гласит
Каждая специализация шаблона функции, созданная из шаблона, имеет свою собственную копию любой статической переменной.
Я предполагаю (и искренне надеюсь), что функции-члены шаблонного класса обрабатываются одинаково, хотя я не могу найти конкретный язык, который говорит об этом.
В любом случае, кроме обычных рисков, связанных с инициализацией статических переменных в многопоточном контексте, я уверен, что это будет хорошо. A<true>::A()
(и внутренний «static int A<true>::A::x
«) будет отмечен как слабые символы, и одна версия будет выбрана во время ссылки, как и любой другой шаблон. (Очевидно, что экземпляр A<false>
будет отличаться от A<true>
.)
Редактировать для комментария:
Беспокойство по поводу различных единиц перевода, по-видимому, покрыто разделом [3.2 / 5], определяющим ODR:
Если D является шаблоном и определяется более чем в одной единице перевода, то … [при условии, что определения идентичны] … программа должна вести себя так, как если бы существовало одно определение D.
Фактические требования немного больше языковой юрисдикции (зависимые имена в момент создания экземпляра должны быть одинаковыми и т. Д. И т. Д.), Но я думаю, что это то, что дает вам ясность 🙂
Других решений пока нет …