Не знаю, правильно ли я попал, ибо эти
проблемы связаны сугубо с wndows dll и
VC 6.0.
Словом, имеются следующие классы
(все сильно утрировано

) :
struct Mummy
{
Mummy() {puts("mummy ctor");}
~Mummy() {puts("mummy dtor");}
};
template <class C>
struct Templ
{
static int *foo();
private:
static int i;
};
template <class C>
int *Templ<C>::foo()
{
static Mummy mum;
return &i;
}
template <class C>
int Templ<C>::i = 0;
Все юзают Templ из разных dll-ек, ожидая получить
один и тот же результат ф-ции foo, которая возвращает
адрес статического члена класса, для одних и тех же
instantiations (как бы это по русски?) класса Templ<C>.
Все бы хорошо, но когда выбираем опцию вставки
inline-функций в код, то это не работает. Очевидно,
экземпляр Templ<TheClass>::i вставляется в каждую dll.
Чтобы пофиксить такой непорядок, я экспортирую
instantiations шаблона Templ<C> для конкретных
классов С, которые у меня используются. Т.е.
экземпляр Templ<TheClass>::i теперь находится
в TheClass.dll, и все с радостью его юзают.
Типа так:
TheClass.h : extern template struct THECLASSDLL_API ::Templ<TheClass>;
TheClass.cpp: int Templ<TheClass>::i = 0;
Первая проблема: таких классов TheClass довольно много,
и нужно перелопатить кучу кода, да и к тому же это дело
надо окружать #ifdef-ом, потому как это ms-specific
extension, а код — multi-platform.
Вторая проблема: тело функции foo надо вставлять внутрь
класса Templ, иначе не компилируется. Это не очень
желательно, поскольку foo довольно больших размеров.
Третья проблема: не вызывается конструктор Mummy!!???
Пофиксино путем переноса mum в члены класса Templ.
Спрашивается — есть ли какие-то обходные маневры для
решения этих проблем.
ЗЫ. Спасибо, если дочитали до конца
Serge.
Hасколько проще была бы жизнь, если бы она была в исходниках.
Здравствуйте, Sergeem, Вы писали:
Попробуй так:
template <class C>
struct Templ
{
#pragma auto_inline (off)
static int *foo();
#pragma auto_inline (on)
private:
static int i;
};
Здравствуйте, Bell, Вы писали:
B>Здравствуйте, Sergeem, Вы писали:
B>Попробуй так:
B>
B>B>template <class C>
B>struct Templ
B>{
B>#pragma auto_inline (off)
B> static int *foo();
B>#pragma auto_inline (on)
B>private:
B> static int i;
B>};
B>
B>
не помогает!
Templ::i все равно размножается!
Serge.
Hасколько проще была бы жизнь, если бы она была в исходниках.
Здравствуйте, Sergeem, Вы писали:
Ну, есть мысль. Код можно менять? Тогда избавься от этих переменных. Исползуй "синглтон Мейерса" — доступ к статической переменной класса через его же статическую функцию. Это должно помочь решить проблему 1 без каких-либо телодвижений вообще:
template <class C>
struct Templ
{
...
private:
static int& GetI() { static i = 0; return i; }
};
Проблема вторая:
Тело функции-члена foo не надо вставлять внутрь определения класса, если только это не функция-шаблон. Её внешний вид будет следующим:
template <class C>
int* Templ<C>::foo()
{
...
return &/*Templ<C>::*/GetI();
}
S>Третья проблема: не вызывается конструктор Mummy!!???
В "утрированном" коде объект не используется, и, вероятно, выкидывается. Нужно его использовать. Например, попросить его адрес:
static Mummy mum, *pmum = &mum;