Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Вопрос про template


Автор: Ivan. 17.8.2016, 15:09
Есть шаблонный класс:
Код
template<typename Type>
struct My {
    Type v;
};
Все просто, класс My принимает какой то тип и описывает у себя поле данного типа.

Если мне нужно принять какой то шаблонный тип, то пишется так:
Код
template<template<typename T> class Type>
struct My {
    Type<int> v;
};
В данном случае я четко описываю, что класс My ожидает не просто тип, а шаблонный тип вида template<typename T> (где T ни как не участвует, он здесь просто для читаемости и его можно опустить)

Третий вариант, работа с вложенным типом:
Код
template<typename Type>
struct My {
    typename Type::Q v;
};
Здесь я ожидаю какой то тип, у которого есть вложенный тип Q. Чтобы компилятор понимал, что Q это именно тип, а не что-то иное нужно пояснить, написав typename.

И четвертый проблемный вариант. Я ожидаю увидеть тип с вложенным шаблонным типом Q:
Код
template<typename Type>
struct My {
    typename Type::Q<int> v; //error
    template<typename> class Type::Q<int> v; //error
};
Как описать, что вложенный тип Q не просто тип, а шаблонный тип?

Обращу внимание, что когда описывается шаблон можно использовать как template<class>, так и template<typename>, но второй вариант более правильный.
но когда описывается шаблонный тип: template<template<typename> class Type> в данном месте обязательно писать class

Автор: baldman88 17.8.2016, 16:24
Странные извраты. Может так?
Код
template<typename Type>
struct My {
    typename Type::template Q<int> v;
};
Сам не пробовал, просто догадка. Если не работает -- я не виноват  smile 

Автор: Ivan. 17.8.2016, 19:02
Огромное спасибо, РАБОТАЕТ. я уже всю голову сломал.

пользуясь случаем, спрошу еще одну вещь у умных людей.
как я уже сказал выше, при описании шаблонного типа шаблона:
Код
template<template<typename T> class Type>
к типу T доступа нет, оно здесь для красоты.
но можно узнать об типе T с помощью специализации:
Код
template<typename>
struct My;
template<template<typename> class Type, typename T>
struct My<Type<T>> {
    T value;
};
Вопрос в следующем, а как сделать специализацию для using?
Код
template<typename>
using My;
template<template<typename> class Type, typename T>
using My<Type<T>> = T;

Автор: baldman88 18.8.2016, 10:37
Что-то я ничего не понял. Чего Вы хотите добиться?

Автор: Ivan. 18.8.2016, 10:57
Ну пример здесь не самый удачный. я просто хочу специализировать using, или это вообще не возможно?
Напомню, что делает using. using - это новая реализация typedef:
Код
typedef int MyInt; //Старый вариант определения типа MyInt как int;
using MyInt = int; //Новый вариант переопределения типа

Новый вариант в отличии от старого поддерживает шаблоны:
Код
template<typename T>
using NewClass = MyClass<T>; //Определяет новый шаблонный тип NewClass идентичный MyClass с передачей аргумента шаблона T

А раз новый вариант поддерживает шаблоны - интересно узнать можно ли использовать специализацию для него:
Код
template<typename T>
using NewClass = MyClass<T>;
template<>
using NewClass<int> = MyClass<double>; //error

Автор: baldman88 18.8.2016, 12:28
Код
using NewClass<int> = MyClass<double>;
Так делать нельзя. Создаваемому типу нельзя передавать никаких аргументов (в смысле тому, имя которого идет после using и перед знаком равенства). Считайте, что это просто переменная. Все параметры задаются полсе знака равенства. Можно, например, сделать как-нибудь так:
Код
template<typename T>
class My {
  T value;
};

template<typename>
using MyInt = My<int>;

template<typename>
using MyDouble = My<double>;
А можно и поизголяться (непонятно зачем, но все же можно):
Код
#include <vector>
#include <list>

template<template<typename, typename> class Type, typename T>
class My {
    Type<T, std::allocator<T>> t;
};

template<template<typename, typename> class Type>
using IntContainer = My<Type, int>;

template<template<typename, typename> class Type>
using DoubleContainer = My<Type, double>;

IntContainer<std::vector> i;
DoubleContainer<std::list> d;

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)