Для статической инициализации члена я использую вложенную вспомогательную структуру, которая отлично работает для не templated классов. Однако, если класс-оболочка параметризуется шаблоном, вложенный класс инициализации не создается, если вспомогательный объект не доступен в основном коде. Для иллюстрации, упрощенный пример (В моем случае мне нужно инициализировать вектор).
#include <string>
#include <iostream>
struct A
{
struct InitHelper
{
InitHelper()
{
A::mA = "Hello, I'm A.";
}
};
static std::string mA;
static InitHelper mInit;
static const std::string& getA(){ return mA; }
};
std::string A::mA;
A::InitHelper A::mInit;
template<class T>
struct B
{
struct InitHelper
{
InitHelper()
{
B<T>::mB = "Hello, I'm B."; // [3]
}
};
static std::string mB;
static InitHelper mInit;
static const std::string& getB() { return mB; }
static InitHelper& getHelper(){ return mInit; }
};
template<class T>
std::string B<T>::mB; //[4]
template<class T>
typename B<T>::InitHelper B<T>::mInit;
int main(int argc, char* argv[])
{
std::cout << "A = " << A::getA() << std::endl;
// std::cout << "B = " << B<int>::getB() << std::endl; // [1]
// B<int>::getHelper(); // [2]
}
С g++ 4.4.1:
-
[1] и [2] прокомментировали:
A = Hello, I'm A.
Работает по назначению
-
[1] раскомментирован:
A = Hello, I'm A. B =
Я бы ожидал, что InitHelper инициализирует mB
- [1] и [2] раскоментированы:
A = Hello, I'm A. B = Hello, I'm B.
Работает по назначению - [1] прокомментировал, [2] раскомментировал:
Segfault на статической стадии инициализации в [3]
Таким образом, мой вопрос: это ошибка компилятора или ошибка, встречающаяся между монитором и стулом? И если это так: есть ли элегантное решение (т.е. Без явного вызова статического метода инициализации)?
Большое спасибо за любые предложения и комментарии.
Обновление I:
Это кажется желательным поведением (как определено в стандарте ISO/IEC С++ 2003, 14.7.1):
Если член шаблона класса или шаблон-член явно не создан или явно не специализирован, специализация этого элемента неявно создается, когда специализация ссылается в контексте, который требует определения члена; в частности, инициализация (и любые связанные с ней побочные эффекты) статического члена данных не происходит, если сам статический член данных не используется таким образом, чтобы требовалось определение члена статического данных.