Форум программистов, компьютерный форум, киберфорум
Наши страницы

Помогите разобраться с шаблонами - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ как раскрасить стаистический рисунок? http://www.cyberforum.ru/cpp/thread361148.html
#include <graphics.h> #include <stdlib.h> #include <stdio.h> #include <conio.h> void Box(int x1, int y1, int x2, int y2); int main(void) { int xmax, ymax;
C++ диспечер задач пожалуйста скиньте диспечер задач на с++ или на с# у кого есть, а то вообще времени ни на что не хватает, чтоб еще его делать. http://www.cyberforum.ru/cpp/thread360687.html
Требуется помощь!Робот-фермер.. C++
Доброго времени суток!Требуется помощь ,я только начинаю учить си ++,поэтому прошу проявить терпение в случае чего:). Значит задача такова: Робот фермер различает размер апельсинов (...
C++ Разработка для Windows CE
Доброго времени суток! Подскажите пожалуйста, что используется для разработки ПО для Windows CE 6 и выше? Слышал, что VS 2008 содержит что-то вроде эмулятора. Есть ли более ранние версии VS, которые...
C++ Странная ошибка при сборке nasm http://www.cyberforum.ru/cpp/thread356140.html
всем привет. нужно собрать nasm для вендус. использую MSYS+MinGW. configure прошел успешно. при сборке получаю такое: nasm.h:476:5: error: expected identifier before numeric constant...
C++ Прослушать запись в файл Доброе утро! Стоит задача записи некоторых атрибутов в CAD файл (UG) без ее запуска. Если изменять текущие атрибуты в файле без добавления или исключения символов, то файл запускается нормально. но... подробнее

Показать сообщение отдельно
Bers
Заблокирован

Помогите разобраться с шаблонами - C++

06.10.2011, 01:12. Просмотров 1670. Ответов 12
Метки (Все метки)

Пытаюсь реализовать новую для себя методику "службы класса".
Все хорошо работало, пока не возникла необходимость в качестве клиента слжбы задействовать не обычный класс, а класс-шаблон.

Впрочем, все по порядку...

Не ругайте за обилие комментариев, я их сделал специально для того, что бы люди смогли понять мою задумку.

Здесь линк на более удобный пастербин:
http://liveworkspace.org/code/c3f887123cde4748cc8aa98e3ba689eb


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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//Служба - свойство класса, инструмент, обслуживающий какие либо
 внутренние потребности класса в чем либо.
//Пример1 - обработка ошибок/исключительных ситуаций, с которыми может столкнуться класс
//Пример2 - что бы любой класс сделать синглтоном, достаточно унаследовать это свойство от специальной службы "синглтон"
 
//методика организации служб
//Основной Принцип работы Службы:
 
// class Клиент: public Служба<Клиент>
// {};
 
//Точная ручная настройка работы службы с самыми нестандартными клиентами 
//достигается за счёт уточнений методов клужбы для конкретного клиента
//В особых ситуациях всегда можно полностью уточнить сам класс службы, а не только отдельные его методы
//Для схожих классов можно использовать дефолтные реализации
//Это напоминает молиформизм, только статический, времени компиляции.
 
//Но есть проблемма. Если класс клиент - сам является шаблоном...
 
// template<Адаптер>
// class Клиент: public Служба< Клиент<адаптер> >
// {};
 
//Проблемма в том, что чтобы уточнять методы службы, необходимо 
//к этому моменту уже знать точное значение параметра <адаптер>
 
// Мне необходимо придумать способ, как можно уточнять отельные методы службы, 
// для всего параметра службы Клиент<адаптер>, 
// не зная при этом, какой конкретнвй адаптер будит использован
 
// Насколько мне известно, это называется "частичная специализация". И что частично специализировать функцию - нельзя
// Однако, наверняка существуют обходные пути...
 
// Ниже представленный код - не рабочий. У меня просто уже плавятся мозги от этих шаблонов. 
// Возможно ошибка там довольно простая
 
 
#include <typeinfo>
#include <iostream>
#include "GlobDefines.h"
 
#define MESSAGE(text1, ClassName, text2) std::cout<< text1<< typeid(ClassName() ).name()<<text2<<std::endl;
 
//описание службы
template<class className>
class TIConsole
{ 
public:
    TIConsole(){ ConstructorFalse(); } //Защита от дурака.
    //Не существует тела функции ConstructorFalse
    //Попытка вызвать такой конструктор приведёт к ошибке компиляции
    //Каждый класс-клиент первым делом уточнит конструктор службы, 
    //и в этой уточненной версии не произойдёт вызова этой функции
 
    //Таким образом службу можно создавать только для конкретных классов-клиентов
    //запихать в качестве параметра службы все что угодно уже не получится
    
    void PrintText() {  MESSAGE("Запущен метод TIConsole<", className, ">::PrintText()"); }
protected:
    void ConstructorFalse(); //попытка вызвать этот метод приведёт к ошибке компиляции
    void ConstructorTrue() { MESSAGE("Разрешение на создание экземпляра класса TIConsole<", className, "> полученно"); }
};
 
//уточненное описание класс TIConsole специально расчитанное на то, 
//что бы можно было в качества параметра шаблона передавать не просто класс, а шаблонн. 
//создавать объекты типа TIConsole< Шаблон<тип>  >
template<  class adapterName, template<class adapterName> class className >
class TIConsole< className<adapterName> >:public TIConsole<adapterName>
{ 
public: 
    //на эту строчку укажет компилятор сигнализируя об ошибке, которую я пытаюсь устранить
    //Причина ошибки - ниже.
    TIConsole() { MESSAGE("Запущен конструктор TIConsole<", className<adapterName>, " >"); }
};
 
//описание враппера
template<class adapterName>
class TConsoleWrapper:public TIConsole< TConsoleWrapper<adapterName> >
{ 
public:    
    TConsoleWrapper() {   ConstructorFalse(); } //Защита от дурака.
};
 
//уточнение враппера
template <>
TConsoleWrapper<SystemAdapter>::TConsoleWrapper() 
{ 
    MESSAGE("Переопределяю конструктор TConsoleWrapper<", SystemAdapter, ">");
    ConstructorTrue(); //получает разрешение на использование конструктора 
    //только для конкретного параметров шаблона SystemAdapter
}
 
//уточнение TIConsole для враппера
template<  class adapterName, template<class adapterName> class TConsoleWrapper >
TIConsole<TConsoleWrapper<adapterName> >::TIConsole() 
{ 
    //Смысл уточнения: 
    //TIConsole<TConsoleWrapper<adapterName> > должен получить разрешение на использование 
    //конструктора независимо от парметра шаблона adapterName
    ConstructorTrue(); 
    MESSAGE("Переопределяю конструктор TIConsole<", TConsoleWrapper<adapterName>, ">");
    //Ошибка компилятора:
    //error C2995: TIConsole<className<adapterName>>::TIConsole(void): шаблон функции уже определен
    //Помогите найти ошибку!
}
 
//Этот пример иллюстрирует как получать разрешения на использование конструктора
//для не шаблонных параметров TIConsole
//А данном случае разрешение будит полученно для клиента службы - SystemAdapter
template <>
TIConsole<SystemAdapter>::TIConsole() 
{ 
    ConstructorTrue(); 
    MESSAGE("Переопределяю конструктор TIConsole<", SystemAdapter, ">");
}
 
 
 
 
 
int main (void)
{
    using namespace std;
    TConsoleWrapper<SystemAdapter> my;
 
    EndProgramm();
}
Добавлено через 3 часа 25 минут
вот здесь линк иллюстрирующий задачу:
http://liveworkspace.org/code/0ed15c936c39d2ef6259469bf21672dc
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru