template <class _T>
class TName {
protected:
_T member ;
public:
_T get() { return( member ) ; }
void Set( _T v ) { member = v ; }
здесь еще 100 тысяч методов :)
} ;
надо для определенного типа изменить только реализацию методов get и set, оставив дефолтную для всех остальных методов. Думал что можно это провернуть через специализацию, но не выходит каменный цветок или я глобально не прав?
ЗЫ. Поискал по инету, описания не дают ответ на мой вопрос, а примеры состоят либо из одного метода, либо все методы и члены класса специализируются.
Здравствуйте, gwg-605, Вы писали:
G6>Есть темплейт:
G6>
G6>template <class _T>
G6>class TName {
G6>protected:
G6> _T member ;
G6>public:
G6> _T get() { return( member ) ; }
G6> void Set( _T v ) { member = v ; }
G6> здесь еще 100 тысяч методов :)
G6>} ;
G6>
G6>надо для определенного типа изменить только реализацию методов get и set, оставив дефолтную для всех остальных методов. Думал что можно это провернуть через специализацию, но не выходит каменный цветок или я глобально не прав?
G6>ЗЫ. Поискал по инету, описания не дают ответ на мой вопрос, а примеры состоят либо из одного метода, либо все методы и члены класса специализируются.
Может сами метотды get и set сделать шаблонными и сделать им специализации?
G6>template <class _T>
G6>class TName {
G6>protected:
G6> _T member ;
G6>public:
G6> _T get() { return( member ) ; }
G6> void Set( _T v ) { member = v ; }
G6> здесь еще 100 тысяч методов :)
G6>} ;
G6>
G6>надо для определенного типа изменить только реализацию методов get и set, оставив дефолтную для всех остальных методов. Думал что можно это провернуть через специализацию, но не выходит каменный цветок или я глобально не прав?
template<> ТотСамыйТип TName<ТотСамыйТип>::get()
{
// Тут реализация
}
template<> void TName<ТотСамыйТип>::Set( ТотСамыйТип v )
{
// Тут реализация
}
Правда поля у класса будут те же. Поментяь сможешь только тела самих методов.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, pavel.yurchenko, Вы писали:
PY>Может сами метотды get и set сделать шаблонными и сделать им специализации?
Тогда уж проще написать прямо в шаблоне методы для того самого типа, но так, чтобы если параметр шаблона не тот, методы не скомпилировались...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, gwg-605, Вы писали:
G6>надо для определенного типа изменить только реализацию методов get и set, оставив дефолтную для всех остальных методов. Думал что можно это провернуть через специализацию, но не выходит каменный цветок или я глобально не прав?
Способ номер раз: ответ на твой вопрос
template<class T> class X
{
T get() {...}
void set(T) {...}
T foo();
void bar() {...}
};
// специализацияtemplate<> inline int X<int>::get() {!!!}
template<> char X<char>::get();
// инстанцирование шаблона (объявление)template int X<int>::foo();
template char X<char>::foo();
// где-то в .cpptemplate<class T> T X<T>::foo() {...}
template<> char X<char>::get() {???}
Способ номер два:
template<class T> class getset // и специализируй его сколько влезет
{
T data;
public:
T get() {...}
void set(T) {...}
};
template<class T> class X : public getset<T>
{
.......
};
Этот подход и идеологически чище, и даёт больше возможностей, поскольку частичная специализация функций невозможна, а с классами творят чудеса.
Способ номер три:
template<class T> class X;
// семейство внешних функцийtemplate<class T> T getx(X<T>&);
template<class T> void setx(X<T>&);
Удобен тем, что можно вместо специализации шаблонов использовать перегрузку и тоже творить чудеса.
Но надо быть очень аккуратным с порядком объявления того и другого — там есть ряд неочевидных граблей, связанных с областями видимости.
Против этих граблей можно побороться, запихав внешние функции в шаблон класса, а дальше см. номер два и номер три рекурсивно
Здравствуйте, Кодт, Вы писали:
К>Способ номер два: К>
К>template<class T> class getset // и специализируй его сколько влезет
К>{
К> T data;
К>public:
К> T get() {...}
К> void set(T) {...}
К>};
К>template<class T> class X : public getset<T>
К>{
К> .......
К>};
К>
К>Этот подход и идеологически чище, и даёт больше возможностей, поскольку частичная специализация функций невозможна, а с классами творят чудеса.
второй способ очень красивый. Не удержался и сам попробовал:
template<class T> class getset // и специализируй его сколько влезет
{
T data;
public:
T get() { return data; }
void set(T value) { data = value; }
};
template<> class getset<int> // и специализируй его сколько влезет
{
int data;
public:
int get() { return -1; }
void set( int data ) { data = -2; }
};
template<class T> class X : public getset<T>
{
};
int main( int argc, char * argv[] )
{
std::cout << "test" << std::endl;
typedef float floatType;
typedef int intType;
X<floatType> fName;
fName.set( 10.5 );
std::cout << "float instance value = " << fName.get() << std::endl;
X<intType> iName;
iName.set( 9 );
std::cout << "int instnce value = " << iName.get() << std::endl;
return 0;
}
На выводе:
testfloat instance value = 10.5
int instnce value = -1