Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.78/9: Рейтинг темы: голосов - 9, средняя оценка - 4.78
 Аватар для Виктор_Сен
36 / 29 / 2
Регистрация: 01.08.2011
Сообщений: 176

Специализация шаблона для стандартных типов

09.03.2015, 16:52. Показов 1759. Ответов 3
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Пишу динамическую структуру данных (не суть важно какую, допустим для простоты стек). Она работает с объектами типа Box, которые: 1. содержат служебную информацию (адрес следующего элемента, и другую); 2. содержат полезную информацию; 3. определены как шаблоны; 4. также используются в других структурах, или существуют отдельно от стека, чтобы их можно было передавать между разными стеками (списками и т. д.). Возникла идея сделать так:
C++
1
2
3
4
5
6
7
template<typename T> struct Box: public T
{
private:
    friend class List<T>;
    Box<T>* next;
    и ещё что-нибудь, допустим для кольцевых списков Box<T>* prev;
};
В "T" здесь хранится полезная информация. Такая запись удобна тем, что можно со структурой Box работать методами из "T". Не нужно писать например "my_box->x->any_field" (если бы в структуре Box было public поле T x), достаточно "my_box->any_field". Да, это всё только из-за того, чтобы не писать пару лишних букв. Просто у меня сложная конструкция, и лень много раз писать "... ->x-> ...". Только проблема в том, что если в качестве "T" будет int или другой стандартный тип, это не будет компилироваться. В остальных случаях нормально работает. Есть ли способ задать специализацию шаблона для всех стандартных типов сразу (отдельно от пользовательских типов). То есть можно ли как-то различать typename T - это стандартный тип, или структура (класс). Подозреваю, что нет, но всё-же. В C# таких проблем бы не было. Можно ещё в Box создать поле T x для всех типов и определить оператор преобразования типа operator T& () для Box. Но тогда придётся писать "(*my_box).any_field" уже для пользовательских типов, что не сокращает число букв. Ещё есть вариант такой:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
template<typename T> struct _ {};
 
template<typename T> struct Box: public T
{
private:
    friend class List<T>;
    Box<T>* next;
    и ещё что-нибудь, допустим для кольцевых списков Box<T>* prev;
};
 
template<typename T> struct Box<_<T>>
{
public:
    operator T& ()
    {
        return x;
    }
    T operator = (T data)
    {
        x=data;
        return data;
    }
    Box<_<T>>(T data): x(data) {}
    Box<_<T>>(){}
private:
    T x;
    friend class List<_<T>>;
    Box<_<T>>* next;
    и ещё что-нибудь, допустим для кольцевых списков Box<_<T>>* prev;
}
 
int main()
{
    Box<MyType>* user_t=...;//Если пользовательский тип
    Box<_<int>>* standard_t=...;//Если стандартный тип данных
    user_t->my_any_method();
    *standard_t=4;
    Stack<_<int>> stack;
    stack.push(standard_t);
    Stack<MyType> stack_my_t;
    stack_my_t.push(user_t);
}
Так работает в обоих случаях, если вручную указывать, что имеется ввиду стандартный тип данных. Можно ли это сделать ещё как-нибудь?

Добавлено через 24 минуты
Здесь получается частичная специализация сразу для нескольких типов сразу.

Добавлено через 3 минуты
P. S. прошу прощения за быдлокод, писалось на коленке, только с целью передать идею. Если это сложно воспринять, могу написать более читабельный вариант со всеми недостающими элементами.
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
09.03.2015, 16:52
Ответы с готовыми решениями:

Явная специализация шаблона для пользовательского типа
Здравствуйте! Сразу извиняюсь если вопрос покажется глупым, перечитал справочник по шаблонам, но так и не нашёл ответ. Есть шаблон класса: ...

Для чего нужна частичная специализация шаблона класса?
Доброго времени суток объясните пожалуйста зачем нужна частичная специализация шаблонов класса

Специализация шаблона для char * (рабочий код, но непонятно почему)
Явное определение специализации – это такое определение, в котором за ключевым словом template следует пара угловых скобок &lt;&gt;, а за...

3
 Аватар для DiffEreD
1458 / 795 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
09.03.2015, 19:33
Лучший ответ Сообщение было отмечено Виктор_Сен как решение

Решение

Перегрузить через enable_if. Как то так, если я правильно понял:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
struct A {
   typedef std::vector<int> some_type;
};
 
struct B {
};
 
template <typename T, typename Enable = void>
class Test;
 
 
template <typename T>
struct Test<T, typename std::enable_if<std::is_same<T, A>::value>::type>
{
   typedef typename T::some_type some_type;
};
 
template <typename T>
struct Test<T, typename std::enable_if<std::is_fundamental<T>::value>::type>
{
   typedef T some_type;
};
 
int main()
{
   static_assert(std::is_same<Test<A>::some_type, std::vector<int>>::value, "");
   static_assert(std::is_same<Test<double>::some_type, double>::value, "");
   //Test<B> test; // Error
 
}
1
 Аватар для Виктор_Сен
36 / 29 / 2
Регистрация: 01.08.2011
Сообщений: 176
11.03.2015, 18:01  [ТС]
В общем это то, что нужно. Ну почти то, в моём варианте получилось так (если без лишнего):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
template<typename T, typename Enable=void> 
class Container;
 
template<typename T> 
class Container<T,typename std::enable_if<std::is_scalar<T>::value>::type>
{
public:
    Container<T,typename std::enable_if<std::is_scalar<T>::value>::type>()
    {
        std::cout<<"I scalar container from "<<typeid(T).name()<<std::endl;
    }
};
 
template<typename T> 
class Container<T,typename std::enable_if<std::is_class<T>::value>::type>: public T
{
public:
    Container<T,typename std::enable_if<std::is_class<T>::value>::type>()
    {
        std::cout<<"I object container from "<<typeid(T).name()<<std::endl;
    }
};
 
class SomeClass
{
 
};
 
int main()
{
    Container<SomeClass> x;
    Container<int> y;
    Container<int*> z;
    system("pause");
    return 0;
}
0
11.03.2015, 18:14

Не по теме:

Конструктора в классах можно не параметризировать:

C++
1
2
3
4
5
6
7
8
9
template<typename T>
class Container<T,typename std::enable_if<std::is_scalar<T>::value>::type>
{
public:
    Container()
    {
        std::cout<<"I scalar container from "<<typeid(T).name()<<std::endl;
    }
};

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
11.03.2015, 18:14
Помогаю со студенческими работами здесь

специализация шаблона
Добрый день! Хотелось бы сделать шаблонную функцию, у которой будет различная реализация в зависимости от того является ли шаблонный...

специализация шаблона
начал разбираться с шаблонами. если есть структура, и одна функция именно с int должна работать по особенному, написать можно вот так. ...

Специализация шаблона
Здравствуйте! Задача: Создайте шаблонную функцию maxn(), которая принимает в качестве аргумента массив элементов типа Т и целое...

Специализация шаблона
Всем доброго вечера! Возникает непонятная ошибка при создании специализации родового класса cl. В строке 10: template class...

Специализация шаблона
Пытаюсь специализировать шаблон для типа float, но не получается. В чем проблема? Компилятор: 1&gt;TemplateArr.obj : error LNK2005:...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит переходные токи и напряжения на элементах схемы. . . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru