template<class T> class TestTemplate;
class TestClass;
template<class T> void Foo(){ std::cout << "class\n"; }
template<template<class> class T> void Foo(){std::cout << "template<class>\n";
...
Foo<TestTemplate>();
Foo<TestClass>();
Задача в том, чтобы таким же образом специализировать шаблон класса, грубо говоря:
template<class T> class TestTemplate;
class TestClass;
template<class T> class Bar { static void print(){std::cout << "class\n";} };
template<template <class> class T> class Bar { static void print(){std::cout << "template<class>\n";} };
...
Bar<TestTemplate>::print();
Bar<TestClass>::print();
Не выходит каменный цветок.
Re: Специализация шаблона класса шаблонным параметром
Я так понимаю в этом случае у тебя никакой специализации нет. Зато есть перегрузка.
NV> Задача в том, чтобы таким же образом специализировать шаблон класса, грубо говоря: NV>
NV> template<class T> class Bar { static void print(){std::cout << "class\n";} };
NV> template<template <class> class T> class Bar { static void print(){std::cout << "template<class>\n";} };
NV>
ИМХО, не получится так. Если мы специализируем первый вариант (где передается тип T), то параметром в любом случае будет ожидаться тип. Если мы специализируем второй вариант (где передается шаблон), то параметром в любом случае будет ожидаться шаблон. Чтобы превратить шаблон в тип, нужно его инстанцировать. Иными словами аргументы шаблона в такой ситуации нужно будет тоже передать так или иначе.
Здравствуйте, NikolayVoronetskiy, Вы писали:
NV>Не выходит каменный цветок.
По моему разумению, шаблонные параметры лучше оборачивать. Потому что они жёстко фиксируют сигнатуру шаблона.
Вот например,
template< template<typename>class T > struct Foo { T<int> ti; };
// кандидаты в параметры для Footemplate<class X> struct A {};
template<class X, class Y=void> struct B {};
// проверяем с одним параметром
A<int> ai;
B<int> bi;
// пытаемся подставить
Foo<A> fa;
Foo<B> fb; // фигушки
Но если мы внесём промежуточный слой в виде метафункции, всё будет хорошо
template<class T> struct def_type { typedef T type; };
struct MakeA { template<class X> struct make : def_type< A<X> > {}; };
struct MakeB1 { template<class X> struct make : def_type< B<X> > {}; }; // можем использовать умолчания целевого шаблонаstruct MakeB2 { template<class X, class Y=void> struct make : def_type< B<X,Y> > {}; }; // а можем и свои умолчания вводитьtemplate<class Maker> struct Foo
{
typename Maker::template make<int>::type ti;
};
Foo<MakeA> fa;
Foo<MakeB1> fb1;
Foo<MakeB2> fb2;
Перекуём баги на фичи!
Re: Специализация шаблона класса шаблонным параметром
Здравствуйте, wander, Вы писали:
W>Я так понимаю в этом случае у тебя никакой специализации нет. Зато есть перегрузка.
Да перегрузка, я просто проиллюстрировал чего конкретно хочется добиться концептуально, мне фактически нужна не специализация, а именно "перегрузка" шаблона, те 2 шаблона с одинаковым именем, но разным набором параметров
W>ИМХО, не получится так. Если мы специализируем первый вариант (где передается тип T), то параметром в любом случае будет ожидаться тип. Если мы специализируем второй вариант (где передается шаблон), то параметром в любом случае будет ожидаться шаблон. Чтобы превратить шаблон в тип, нужно его инстанцировать. Иными словами аргументы шаблона в такой ситуации нужно будет тоже передать так или иначе.
Пока именно искомого решения действительно не найдено.
Re[2]: Специализация шаблона класса шаблонным параметром
Здравствуйте, Lucky Cat, Вы писали:
LC>Здравствуйте, NikolayVoronetskiy, Вы писали:
NV>>Задача в том, чтобы таким же образом специализировать шаблон класса, грубо говоря:
LC>Может нужно не шаблон класса специализировать, а специализировать шаблонную функцию-член класса?
Нет к сожалению мне нужна не функция, а мне нужно следующее если говорить конкретно:
template<class C, class T> class Bar { typedef T Type; };
template<class C, template <class> class T> class Bar { typedef T<C> Type; };
Re[3]: Специализация шаблона класса шаблонным параметром
Здравствуйте, NikolayVoronetskiy, Вы писали:
NV>Спасибо за отклик! Да в какой-то степени это является решением, к сожалению лучше пока ничего не нашёл.
лучше и не надо.
более подробно смотри "C++ Template Metaprogramming: Concepts, Tools, and Techniques from Boost and Beyond"
Re[3]: Специализация шаблона класса шаблонным параметром
Здравствуйте, NikolayVoronetskiy, Вы писали:
NV>Спасибо за отклик! Да в какой-то степени это является решением, к сожалению лучше пока ничего не нашёл.
Да, я ж забыл — надо было специализировать, в зависимости от арности метафункции.
Придётся немного вывернуться.
По-прежнему, будем в метафункцию передавать параметры одного и того же вида (kind) — а именно, конкретные классы.
Различать же станем по этим классам. Причём со всей мощью С++ного паттерн-матчинга!
Заметим: wrap_unary<T> имеет вид "class", а не "template<class>class". Но его можно сопоставить — извлечь его параметр искомого вида.
В принципе, основной шаблон можно было и не определять, оставив только две специализации. Ибо нефиг смешивать голые и обёрнутые параметры.
Или можно выкинуть специализацию для wrap_final — пусть вместо этого работает основной шаблон с голым параметром.
Перекуём баги на фичи!
Re[3]: Специализация шаблона класса шаблонным параметром
Здравствуйте, NikolayVoronetskiy, Вы писали:
NV>>>Задача в том, чтобы таким же образом специализировать шаблон класса, грубо говоря: LC>>Может нужно не шаблон класса специализировать, а специализировать шаблонную функцию-член класса?
NV>Нет к сожалению мне нужна не функция, а мне нужно следующее если говорить конкретно:
NV>
NV>template<class C, class T> class Bar { typedef T Type; };
NV>template<class C, template <class> class T> class Bar { typedef T<C> Type; };
NV>
Возможно, все проще?
// The primary templatetemplate<class T>
class Bar
{
public:
typedef T Type;
};
// A partial specialization for templates with single type parametertemplate<class C, template <class> class T>
class Bar<T<C> >
{
public:
typedef T<C> Type;
};
// Use casesclass TestClass { };
template<class T> class TestTemplate { };
Bar<TestClass>::Type a;
Bar<TestTemplate<int> >::Type b;
--
Справедливость выше закона. А человечность выше справедливости.