Аннотация :
Время от времени при работе с шаблонами возникает необходимость специализировать шаблон класса по одному из аргументов. В качестве примера можно рассмотреть шаблон классов матриц, параметризованный типом элемента и размерами матрицы. Однако некоторые компиляторы не поддерживают частичную специализацию, и, как следствие, «не понимают» подобные конструкции. Желание получить эквивалентную функциональность при работе с такими компиляторами приводит к технике, описанной ниже.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
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>
{
//...
};
Здравствуйте, 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.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Andrew S, Вы писали:
AS>Кстати, еще неплохо было бы дабавить IsArray, который таки почти смог добить Андрей Тарасевич в одном из топиков форума С++
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Здравствуйте, 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.]
[Даю очевидные ответы на риторические вопросы]
AS>PS Павел, кстати, эту же статью от вас я уже видел в каком то online издании.. Или я ошибаюсь?
Действительно, в первый раз статья появилась dev.dtf.ru, но в данном виде, исправленном и дополненном, впервые она была опубликована именно на RSDN.ru.
Есть такая библиотека Loki. В ней автор очень "глубоко" работает с шаблонами. Я бы это даже назвал программированием на этапе компиляции.
Там есть всё это и многое другое.
Здравствуйте, Mistery, Вы писали:
M>Здравствуйте, Павел Кузнецов,
M>Есть такая библиотека Loki. В ней автор очень "глубоко" работает с шаблонами. Я бы это даже назвал программированием на этапе компиляции. M>Там есть всё это и многое другое.
Хочется обратить внимание на еще одну интересную работу (извините, что не в тему чуть) некоего И.Ньютона "Математические начала натуральной философии". В ней автор очень "глубоко" применяет новую (!) остроумную технику, которую я бы дажне назвал эдаким "дифференциальным исчислением". Ну и еще там есть многое другое.
ПК>Авторы : ПК>Павел Кузнецов
ПК>Аннотация : ПК>Время от времени при работе с шаблонами возникает необходимость специализировать шаблон класса по одному из аргументов. В качестве примера можно рассмотреть шаблон классов матриц, параметризованный типом элемента и размерами матрицы. Однако некоторые компиляторы не поддерживают частичную специализацию, и, как следствие, «не понимают» подобные конструкции. Желание получить эквивалентную функциональность при работе с такими компиляторами приводит к технике, описанной ниже.
В статье в нескольких местах есть код типа:
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 >
{
// . . .
};
Здравствуйте, 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 там не нужен, он избыточен. Поэтому все работает.