2012-01-29 3 views
2

У меня есть класс X ...шаблон Специализация и статический Locals

class X {...} 

и я хочу иметь один экземпляр X для каждого отдельного типа некоторого множества типов. (Некоторые из этих типов не классы и/или не написанные мной.)

Чтобы сделать это, я подумал:

template<typename T> X& XT(); 

, а затем для каждого типа A, B и C:

template<> X& XT<A>() { static X x; return x; } 
template<> X& XT<B>() { static X x; return x; } 
template<> X& XT<C>() { static X x; return x; } 

Будет ли это работать? Это лучший способ сделать это? Каковы альтернативные способы?

+1

Это довольно умный. Я не могу придумать никаких причин, почему это не сработает. – StilesCrisis

+0

Вы пробовали попробовать? – Mehrdad

+0

Для меня вопрос еще не ясен. – iammilind

ответ

1

Вам не нужно специализировать функцию. Вы можете просто сделать это:

template<typename T> 
X& XT() 
{ 
    static X x; 
    return x; 
} 

И использовать его как:

X &xa = XT<A>(); 
X &xb = XT<B>(); 
X &xc = XT<C>(); 
X &xd = XT<A>(); //xd is same as xa 

Все три объекта xa, xb и xc являются различные экземпляры X. Однако xa и xd такие же случаи, когда они оба называют одну и ту же функцию.

Следует отметить, что компилятор создает различные функции для каждого аргумента шаблона. Таким образом, XT<A>() отличается от XT<B>(), и каждая функция имеет свои собственные локальные переменные static. Таким образом, локальная переменная static в XT<A>() является другим экземпляром, чем переменная в XT<B>().

0

Вам даже не нужно определять каждый по отдельности:

#include <iostream> 

template<typename T, typename X> 
struct static_holder { 
    static T static_instance; 
}; 

template<typename T, typename X> 
T static_holder<T,X>::static_instance; 

template<typename T, typename X> 
T &get_static_instance() { 
    return static_holder<T,X>::static_instance; 
} 

Теперь вы можете просто определить:

template<typename K> 
X &XT() { 
    return get_static_instance<X, K>(); 
} 

Обратите внимание, что этот метод, вероятно, не в состоянии плохо, если используется через общие границы библиотек ,

+0

в Linux, он будет корректно работать через общие границы библиотек. Я считаю, что в окнах вам нужно что-то делать с 'dllexport' или что-то в этом роде. –

+0

@ JohannesSchaub-litb, у меня были проблемы с подобными вещами у solibs - шаблоны в порядке, но вы обнаружите, что символы не дедуплируются. В моем случае это была информация RTTI, но я подозреваю, что это тоже будет с шаблоном statics. – bdonlan

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