Частичная специализация
От: caxaromires  
Дата: 18.06.11 10:40
Оценка:
Пишу шаблонный класс, в котором реализация одного из методов должна быть одинаковая для всех случаев, кроме одного — когда в качестве параметра передается экземпляр данного шаблонного класса.

template <class X> class TMy
{
public:
...
void push(X value); 
};

void test()
{
TMy<int> q;
q.push( 5 );   //1
TMy<TMy<double> > w;
w.push( TMy<double> (5.5) ); //2
TMy<TMy<int> > e;
e.push( TMy<int> (5) ); //3
//1 и 2 должны быть вызваны разные методы, 2 и 3 - одинаковые
}



Смог выполнить задуманное сделав частичную специализацию класса

template <A> class TMy<TMy<A> >
{
public:
void push(TMy<A> value);
}


Но понадобилось переопределять все методы класса. Можно ли задать частичную специализацию метода шаблонного класса(если вопрос слегка корявый, то его суть — неохота переопределять все методы класса для данной специализации)?
Re: Частичная специализация
От: Centaur Россия  
Дата: 18.06.11 12:00
Оценка:
Здравствуйте, caxaromires, Вы писали:

C>Смог выполнить задуманное сделав частичную специализацию класса


C>template <A> class TMy<TMy<A> >
C>{
C>public:
C>void push(TMy<A> value);
C>}


C>Но понадобилось переопределять все методы класса. Можно ли задать частичную специализацию метода шаблонного класса(если вопрос слегка корявый, то его суть — неохота переопределять все методы класса для данной специализации)?


Выдели все методы с общей реализацией в базовый класс, от которого унаследуй основной шаблон и частичную специализацию.
Re: Частичная специализация
От: jazzer Россия Skype: enerjazzer
Дата: 18.06.11 12:13
Оценка:
Здравствуйте, caxaromires, Вы писали:

C>Пишу шаблонный класс, в котором реализация одного из методов должна быть одинаковая для всех случаев, кроме одного — когда в качестве параметра передается экземпляр данного шаблонного класса.


C>Но понадобилось переопределять все методы класса. Можно ли задать частичную специализацию метода шаблонного класса(если вопрос слегка корявый, то его суть — неохота переопределять все методы класса для данной специализации)?


Решение с бустом:
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>

template <class X> struct TMy
{
public:
  template <class A>
  typename boost::enable_if< boost::is_same<A, X>, void >::type
  push(A value) { std::cout << "general" << std::endl; }

  template <class A>
  void push(TMy<A> value) { std::cout << "spec" << std::endl; }
};
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: Частичная специализация
От: Centaur Россия  
Дата: 18.06.11 17:34
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Решение с бустом:

J>#include <boost/utility/enable_if.hpp>
J>#include <boost/type_traits/is_same.hpp>

J>template <class X> struct TMy
J>{
J>public:
J>  template <class A>
J>  typename boost::enable_if< boost::is_same<A, X>, void >::type
J>  push(A value) { std::cout << "general" << std::endl; }

J>  template <class A>
J>  void push(TMy<A> value) { std::cout << "spec" << std::endl; }
J>};


Код неэквивалентный. В исходном варианте у TMy<X> был только void push(X), а тут появляется void push(TMy<A>) для любых A.
Re: Частичная специализация
От: Vain Россия google.ru
Дата: 18.06.11 19:20
Оценка: 2 (1) +1
Здравствуйте, caxaromires, Вы писали:

C>Пишу шаблонный класс, в котором реализация одного из методов должна быть одинаковая для всех случаев, кроме одного — когда в качестве параметра передается экземпляр данного шаблонного класса.

C>
C>template <class X> class TMy
C>{
C>public:
C>...
C>void push(X value); 
C>};
C>void test()
C>{
C>TMy<int> q;
C>q.push( 5 );   //1
C>TMy<TMy<double> > w;
C>w.push( TMy<double> (5.5) ); //2
C>TMy<TMy<int> > e;
C>e.push( TMy<int> (5) ); //3
C>//1 и 2 должны быть вызваны разные методы, 2 и 3 - одинаковые
C>}
C>

C>Смог выполнить задуманное сделав частичную специализацию класса
C>
C>template <A> class TMy<TMy<A> >
C>{
C>public:
C>void push(TMy<A> value);
C>}
C>

C>Но понадобилось переопределять все методы класса. Можно ли задать частичную специализацию метода шаблонного класса(если вопрос слегка корявый, то его суть — неохота переопределять все методы класса для данной специализации)?

Чем это не устраивает:
template <class X> class TMy
{
private:
template<typename T>
void push_impl(T v);
template<typename T>
void push_impl(TMy<T> v);
public:
...
void push(X value) { return push_impl(value); }
};
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[3]: Частичная специализация
От: jazzer Россия Skype: enerjazzer
Дата: 19.06.11 04:49
Оценка:
Здравствуйте, Centaur, Вы писали:

C>Код неэквивалентный. В исходном варианте у TMy<X> был только void push(X), а тут появляется void push(TMy<A>) для любых A.


Ну, это легко исправить:
template <class X> struct TMy
{
public:
  template <class A>
  typename boost::enable_if< boost::is_same<A, X>, void >::type
  push(A value) { std::cout << "general" << std::endl; }

  template <class A>
  typename boost::enable_if< boost::is_same<TMy<A>, X>, void >::type
  push(TMy<A> value) { std::cout << "spec" << std::endl; }
};
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: Частичная специализация
От: caxaromires  
Дата: 20.06.11 05:00
Оценка:
Здравствуйте, Vain, Вы писали:


V>Чем это не устраивает:

V>
V>template <class X> class TMy
V>{
V>private:
V>template<typename T>
V>void push_impl(T v);
V>template<typename T>
V>void push_impl(TMy<T> v);
V>public:
V>...
V>void push(X value) { return push_impl(value); }
V>};
V>


Всем устраивает!) Можно уточнить зачем делать закрытыми push_impl вместо того, чтобы сразу сделать их открытыми?
Re: Определение тела функции вне тела шаблонного класса
От: caxaromires  
Дата: 20.06.11 05:21
Оценка:
Как задать тело функции push вне тела класса?
.h
temlplate <class X, class Y>
class Tmy
{
public:
...
template <class A, class B, class C> void push (C value, TMy<A, B> item);
...
};
Re[3]: Частичная специализация
От: Vain Россия google.ru
Дата: 20.06.11 21:01
Оценка:
Здравствуйте, caxaromires, Вы писали:

V>>Чем это не устраивает:

V>>
V>>template <class X> class TMy
V>>{
V>>private:
V>>template<typename T>
V>>void push_impl(T v);
V>>template<typename T>
V>>void push_impl(TMy<T> v);
V>>public:
V>>...
V>>void push(X value) { return push_impl(value); }
V>>};
V>>

C>Всем устраивает!) Можно уточнить зачем делать закрытыми push_impl вместо того, чтобы сразу сделать их открытыми?
А что тогда в аргумент шаблона передавать?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.