Симуляция частичной специализации
От: Павел Кузнецов  
Дата: 06.03.03 12:01
Оценка: 581 (13)
Статья :
Симуляция частичной специализации
Автор(ы): Павел Кузнецов
Дата: 05.03.2003
Время от времени при работе с шаблонами возникает необходимость специализировать шаблон класса по одному из аргументов. В качестве примера можно рассмотреть шаблон классов матриц, параметризованный типом элемента и размерами матрицы. Однако некоторые компиляторы не поддерживают частичную специализацию, и, как следствие, «не понимают» подобные конструкции. Желание получить эквивалентную функциональность при работе с такими компиляторами приводит к технике, описанной ниже.


Авторы :
Павел Кузнецов

Аннотация :
Время от времени при работе с шаблонами возникает необходимость специализировать шаблон класса по одному из аргументов. В качестве примера можно рассмотреть шаблон классов матриц, параметризованный типом элемента и размерами матрицы. Однако некоторые компиляторы не поддерживают частичную специализацию, и, как следствие, «не понимают» подобные конструкции. Желание получить эквивалентную функциональность при работе с такими компиляторами приводит к технике, описанной ниже.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
А как на VC7 специализировать такие шаблоны?
От: Андрей Россия  
Дата: 20.03.03 09:22
Оценка:
template<class TRet, class TP1>
class CDelegate1
{
  //...
};

template<class TP1>
class CDelegate1<bool, TP1>
{
  //...
};

template<class TRet, class TP1, class TP2>
class CDelegate2
{
  //...
};

template<class TP1, class TP2>
class CDelegate2<bool, TP1, TP2>
{
  //...
};


и т.д.

Исправлена подсветка синтаксиса. -- ПК.
.. и статической T не надо.
От: Andrew S Россия http://alchemy-lab.com
Дата: 07.03.03 14:50
Оценка:
А мне как то больше понравился такой вариант (где нет статического T _t):

template<class T>
class IsPointer
{
private:
struct TrueType  { char dummy_ [1];   };
struct FalseType { char dummy_ [2]; };
struct PointerShim
{
  PointerShim(const volatile void*);
};
static TrueType  ptr_discriminator(PointerShim);
static FalseType ptr_discriminator(...);
static T rett();

public:
  enum { value = sizeof(ptr_discriminator(rett())) == sizeof(TrueType) };
};
template<>
class IsPointer<void>
{
public:
  enum { value = false };
};


Кстати, еще неплохо было бы дабавить IsArray, который таки почти смог добить Андрей Тарасевич в одном из топиков форума С++

PS Павел, кстати, эту же статью от вас я уже видел в каком то online издании.. Или я ошибаюсь?

Исправлена подсветка синтаксиса. -- ПК.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
А ссылку на boost.org?
От: limax Россия http://mem.ee
Дата: 07.03.03 12:01
Оценка:
Почему не указал ссылку на boost.org ?
Там уж намного больше готовых функций, чем ты привёл.
Have fun: Win+M, Ctrl+A, Enter
Re: А как на VC7 специализировать такие шаблоны?
От: Павел Кузнецов  
Дата: 20.06.03 16:51
Оценка:
Здравствуйте, Андрей, Вы писали:

А> template<class TRet, class TP1, class TP2>
А> class CDelegate2
А> {
А>   //...
А> };

А> template<class TP1, class TP2>
А> class CDelegate2<bool, TP1, TP2>
А> {
А>   //...
А> };


Соответственно:

template<class TRet, class TP1, class TP2>
class CDelegate2_
{
  //...
};

template<class TP1, class TP2>
class CDelegate2_bool_
{
  //...
};

template<class TRet>
struct Delegate2_traits
{
  template<class T1, class T2>
  struct Args
  {
    typedef CDelegate2_<TRet, T1, T2> Base;
  };
};

template<>
struct Delegate2_traits<bool>
{
  template<class T1, class T2>
  struct Args
  {
    typedef CDelegate2_bool_<T1, T2> Base;
  };
};

template<class TRet, class TP1, class TP2>
class CDelegate2 : public Delegate2_traits<TRet>::template Args<TP1, TP2>::Base
{
};
Posted via RSDN NNTP Server 1.5 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re: А ссылку на boost.org?
От: Павел Кузнецов  
Дата: 20.06.03 16:53
Оценка:
Здравствуйте, limax, Вы писали:

L>Почему не указал ссылку на boost.org ? Там уж намного больше готовых функций, чем ты привёл.


Целью статьи было не перечисление готовых функций, а демонстрация принципа их построения без использования "натуральной" частичной специализации.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re: .. и статической T не надо.
От: Павел Кузнецов  
Дата: 20.06.03 16:59
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>А мне как то больше понравился такой вариант (где нет статического T _t):


AS>
AS>template<class T>
AS>class IsPointer
AS>{
AS>  static T rett();
AS>  
AS>  enum { value = sizeof(ptr_discriminator(rett())) == sizeof(TrueType) };
AS>


Странно... Мне почему-то следующее кажется короче и проще (как минимум меньше скобочек :) ):

template<class T>
class IsPointer
{
  static T t_;
  
  enum { value = sizeof(ptr_discriminator(t_)) == sizeof(TrueType) };


AS>PS Павел, кстати, эту же статью от вас я уже видел в каком то online издании.. Или я ошибаюсь?


Действительно, в первый раз статья появилась dev.dtf.ru, но в данном виде, исправленном и дополненном, впервые она была опубликована именно на RSDN.ru.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re: .. и статической T не надо.
От: Андрей Тарасевич Беларусь  
Дата: 20.06.03 17:12
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>Кстати, еще неплохо было бы дабавить IsArray, который таки почти смог добить Андрей Тарасевич в одном из топиков форума С++


Окончательно добить его так и не удалось.
Best regards,
Андрей Тарасевич
Re[2]: .. и статической T не надо.
От: Vain Россия google.ru
Дата: 22.09.05 14:12
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Здравствуйте, Andrew S, Вы писали:


AS>>А мне как то больше понравился такой вариант (где нет статического T _t):


AS>>
AS>>template<class T>
AS>>class IsPointer
AS>>{
AS>>  static T rett();
AS>>  
AS>>  enum { value = sizeof(ptr_discriminator(rett())) == sizeof(TrueType) };
AS>>


ПК>Странно... Мне почему-то следующее кажется короче и проще (как минимум меньше скобочек ):


ПК>
ПК>template<class T>
ПК>class IsPointer
ПК>{
ПК>  static T t_;
  
ПК>  enum { value = sizeof(ptr_discriminator(t_)) == sizeof(TrueType) };
ПК>


Хм.. А это ещё и с абстрактными классами под M$ работает:
template<class T>
class IsPointer
{
static T* t_;
enum { value = sizeof(ptr_discriminator(*t_)) == sizeof(TrueType) };
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re: Симуляция частичной специализации
От: sch  
Дата: 22.09.05 14:26
Оценка:
http://dtf.ru/articles/read.php?id=11
Re[2]: Симуляция частичной специализации
От: Alxndr Германия http://www.google.com/profiles/alexander.poluektov#buzz
Дата: 22.09.05 14:38
Оценка:
Здравствуйте, sch, Вы писали:

sch>http://dtf.ru/articles/read.php?id=11


AS>PS Павел, кстати, эту же статью от вас я уже видел в каком то online издании.. Или я ошибаюсь?

Действительно, в первый раз статья появилась dev.dtf.ru, но в данном виде, исправленном и дополненном, впервые она была опубликована именно на RSDN.ru.


http://www.rsdn.ru/Forum/Message.aspx?mid=302672&amp;only=1
Автор: Павел Кузнецов
Дата: 20.06.03
Re: Библиотека Loki
От: Mistery Россия  
Дата: 27.01.06 20:26
Оценка: :))) :))) :)))
Здравствуйте, Павел Кузнецов,

Есть такая библиотека Loki. В ней автор очень "глубоко" работает с шаблонами. Я бы это даже назвал программированием на этапе компиляции.
Там есть всё это и многое другое.
Mistery
Re[2]: Библиотека Loki
От: Warturtle  
Дата: 03.03.06 13:49
Оценка: 12 (1) :))) :)
Здравствуйте, Mistery, Вы писали:

M>Здравствуйте, Павел Кузнецов,


M>Есть такая библиотека Loki. В ней автор очень "глубоко" работает с шаблонами. Я бы это даже назвал программированием на этапе компиляции.

M>Там есть всё это и многое другое.

Хочется обратить внимание на еще одну интересную работу (извините, что не в тему чуть) некоего И.Ньютона "Математические начала натуральной философии". В ней автор очень "глубоко" применяет новую (!) остроумную технику, которую я бы дажне назвал эдаким "дифференциальным исчислением". Ну и еще там есть многое другое.

Re: Симуляция частичной специализации
От: lastique  
Дата: 03.03.06 15:01
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Статья :

ПК>Симуляция частичной специализации
Автор(ы): Павел Кузнецов
Дата: 05.03.2003
Время от времени при работе с шаблонами возникает необходимость специализировать шаблон класса по одному из аргументов. В качестве примера можно рассмотреть шаблон классов матриц, параметризованный типом элемента и размерами матрицы. Однако некоторые компиляторы не поддерживают частичную специализацию, и, как следствие, «не понимают» подобные конструкции. Желание получить эквивалентную функциональность при работе с такими компиляторами приводит к технике, описанной ниже.


ПК>Авторы :

ПК>Павел Кузнецов

ПК>Аннотация :

ПК>Время от времени при работе с шаблонами возникает необходимость специализировать шаблон класса по одному из аргументов. В качестве примера можно рассмотреть шаблон классов матриц, параметризованный типом элемента и размерами матрицы. Однако некоторые компиляторы не поддерживают частичную специализацию, и, как следствие, «не понимают» подобные конструкции. Желание получить эквивалентную функциональность при работе с такими компиляторами приводит к технике, описанной ниже.

В статье в нескольких местах есть код типа:

template<class T, int Rows, int Columns>
class Matrix : public MatrixTraits<T>::template Dimensions<Rows, Columns>::Base
{
  // . . .
};


Это работать не будет, т.к. компилятор захочет typename после public, что запрещено стандартом. В таких случаях следует писать:

template< class T >
struct Inherit : public T
{
};

template<class T, int Rows, int Columns>
class Matrix : public Inherit< typename MatrixTraits<T>::template Dimensions<Rows, Columns>::Base >
{
  // . . .
};
Re[2]: Симуляция частичной специализации
От: Pavel Chikulaev Россия  
Дата: 03.03.06 15:04
Оценка: 15 (1) +2
Здравствуйте, lastique, Вы писали:

L>В статье в нескольких местах есть код типа:


L>
L>template<class T, int Rows, int Columns>
L>class Matrix : public MatrixTraits<T>::template Dimensions<Rows, Columns>::Base
L>{
L>  // . . .
L>};
L>


L>Это работать не будет, т.к. компилятор захочет typename после public, что запрещено стандартом. В таких случаях следует писать:

После public может быть только тип, и typename там не нужен, он избыточен. Поэтому все работает.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.