Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.55/65: Рейтинг темы: голосов - 65, средняя оценка - 4.55
mos80
0 / 0 / 0
Регистрация: 07.03.2010
Сообщений: 233
1

Шаблоны в C++

29.12.2010, 21:19. Просмотров 11788. Ответов 28
Метки нет (Все метки)

Добрый вечер.

Обращаюсь за помощью к "увлекающимся" плюсами.
Вопросов собственно 2:
1. как можно в шаблоне сделать условие. Т.е. в зависимости от значения параметра шаблон различался.
2. можно ли в шаблоне сделать проверку параметров шаблона и в случае не прохождения проверки выдавать ошибки на этапе компиляции.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.12.2010, 21:19
Ответы с готовыми решениями:

Сишные шаблоны реализации конечных автоматов
Давайте поднимем такую интересную темку. Конечные автоматы. Точнее, шаблоны...

Шаблоны проектов на C++ для AVR [GCC, IAR]
Ссылка на svn репозиторий: Шаблоны: https://mysvn.ru/avr/templates/...

Шаблоны проектов на C++ для AVR [GCC, IAR]
Ссылка на svn репозиторий: Шаблоны: https://mysvn.ru/avr/templates/...

Хранить шаблоны документов в базе и выводить данные в эти шаблоны
Доброго времени суток. Интересует вопрос: мне необходимо формировать...

Чем отличаются шаблоны HTML и шаблоны WordPress
В чём различие между шаблонами HTML и WordPress. Кроме того, что создаются они...

28
mos80
0 / 0 / 0
Регистрация: 07.03.2010
Сообщений: 233
07.02.2011, 21:47 21
Цитата Сообщение от miyvir
Поподробнее про задачу можно?
Делаю библиотеку для УАРТА. Хочу описать тип в котором будут присутствовать функции общего назначения, например инициализация включение передатчика, приемника. Так вот для разного камня эти функции могут быть разными, но для некоторых они одинаковы. Не хочется для каждого кристалла делать свою специализацию.
0
miyvir
0 / 0 / 0
Регистрация: 27.06.2010
Сообщений: 405
08.02.2011, 01:25 22
Ключевое слово "классы стратегий".
Код
struct DefaultUsartHW
{
void InitTx(){...}
void InitRx(){...}
void SetBoundRate(uint32_t rate){...}
...
uint8_t ReadRx(){return UDR;}
...
};
template<int TxFifoSize, int RxFifoSize, ctoss UsartHW = DefaultUsartHW>
ctoss Usart
{
...
void Init(uint32_t )
{
UsartHW::SetBoundRate(rate);
UsartHW::InitTx();
UsartHW::InitRx();
...
}
};
Никаких специализаций вовсе не надо. Всё специфичное поведение реализуется в классах стратегиях, общее - в классе их использующим.
0
mos80
0 / 0 / 0
Регистрация: 07.03.2010
Сообщений: 233
08.02.2011, 10:53 23
Цитата Сообщение от miyvir
Ключевое слово "классы стратегий".
Код:
struct DefaultUsartHW
{
void InitTx(){...}
void InitRx(){...}
void SetBoundRate(uint32_t rate){...}
...
uint8_t ReadRx(){return UDR;}
...
};
template<int TxFifoSize, int RxFifoSize, ctoss UsartHW = DefaultUsartHW>
ctoss Usart
{
...
void Init(uint32_t )
{
UsartHW::SetBoundRate(rate);
UsartHW::InitTx();
UsartHW::InitRx();
...
}
};

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

Да, до этого я догадался ).
Теперь нужно для каждого камня описать класс DefaultUsartHW. Так вот у некоторых камней эти процедуры будут одинаковые. Хочется для некой группы сделать одно описание DefaultUsartHW а для другой другое. У меня определен некий тип _MCU который принимает соответствующее значения в зависимости от используемого контроллера. Хочется передать этот тип шаблону, а шаблон сам подберет нужную специалицию.
0
miyvir
0 / 0 / 0
Регистрация: 27.06.2010
Сообщений: 405
08.02.2011, 11:58 24
Как показывает практика, выбирать поведение на основе какого-то значения не очень хорошо. Это может породить проблем больше, чем их решить. Когда во многих местах программы производится такой выбор, и возможных значений этого параметра становится всё больше и больше, вскоре начинается такая каша и петаница...
Я отказался от этого подхода в пользу того, чтобы просто подключать заголовок с нужным определением.
В моей библиотеке для работы портами это работает так:
Каждая специфичная реализация портов находится в своём подкаталоге: AVR, XMEGA, MSP430 и т.д.
Где-то в библиотеке
...
#include "ports.h"
...

А подкаталог с конкретной реализацией выбирается в файле проекта, в makefile-е и т.п. Короче - в системе сборки.
0
mos80
0 / 0 / 0
Регистрация: 07.03.2010
Сообщений: 233
08.02.2011, 12:23 25
Цитата Сообщение от miyvir
Как показывает практика, выбирать поведение на основе какого-то значения не очень хорошо. Это может породить проблем больше, чем их решить. Когда во многих местах программы производится такой выбор, и возможных значений этого параметра становится всё больше и больше, вскоре начинается такая каша и петаница...
Я отказался от этого подхода в пользу того, чтобы просто подключать заголовок с нужным определением.
В моей библиотеке для работы портами это работает так:
Каждая специфичная реализация портов находится в своём подкаталоге: AVR, XMEGA, MSP430 и т.д.
Где-то в библиотеке
...
#include "ports.h"
...

А подкаталог с конкретной реализацией выбирается в файле проекта, в makefile-е и т.п. Короче - в системе сборки.
Просто например меги с 48 по 328 имеют одинаковый модуль уарта, и описывать для каждого одно и тоже немного муторно боюсь будет, хотелось написать список и для него описать один раз. Похоже прийдется дефайнами пользоватся. (
0
miyvir
0 / 0 / 0
Регистрация: 27.06.2010
Сообщений: 405
08.02.2011, 17:23 26
Не прийдётся ничего дублировать. И макросами пользоваться здесь тоже не стоит. Описывать надо только уникальные отличия для разных камней. А выбирать нужный заголовок с этим описанием в системе сборки, в зависимости от типа процессора.
0
miyvir
0 / 0 / 0
Регистрация: 27.06.2010
Сообщений: 405
08.02.2011, 18:41 27
Продолжая тему шаблоны С++ для АВР. Указатель на флеш.
В AVR, как известно различные адресные пространства для оперративки и флеша и разные комманды для доступа к ним. В языках Си\Си++ нет такого понятия как адресное пространство - они разработаны для одного линейного АП. Это создаёт неудобства. У нас есть указатель, но куда он указывает? В оперативку? Во флеш? А может в EEPROM? Надо всё время помнить что у тебя за указатель, куда указывает и какие комманды для работы с ним использовать.
В компиляторе от IAR Systems для решения этой проблемы применено нестандартное решение - модификатор __flash, который по сути создаёт новые типы для размещенных во флеши данных.
Реализуем похожую функциональность средствами Си++.

Код
template<ctoss T, ctoss PtrType = T*>
ctoss ProkmemPtr
{
typedef ProkmemPtr Self;
public:
ProkmemPtr(T *address=0)
:_address(address)
{}

inline Self& operator ++()
{
_address++;
return *this;
}
inline Self operator ++(int)
{
Self tmp = *this;
_address++;
return tmp;
}
inline Self& operator --()
{
_address--;
return *this;
}
inline Self operator --(int)
{
Self tmp = *this;
_address--;
return tmp;
}
inline Self& operator +=(int value)
{
_address += value;
return *this;
}
inline Self& operator -=(int value)
{
_address -= value;
return *this;
}
inline Self operator +(int value)
{
return Self(_address + value);
}
inline Self operator -(int value)
{
return Self(_address - value);
}
inline bool operator !=(const Self &other) const
{
return _address != other._address;
}
inline bool operator ==(const Self &other) const
{
return _address == other._address;
}
inline const T operator *()const
{
union
{
T value;
uint8_t bytes[sizeof(T)];
};
for(unsykned i = 0; i<sizeof(T); ++i)
bytes[i] = pgm_read_byte(_address + i);
return value;
}
pryvate:
PtrType _address;
};
Инициализировав такой "умный" указатель обычным указателем на данные во флеше и пользуемся им почти как обычным указателем, но данные при этом читаются из флеша:
Код
   PROGMEM char Str[] = "Hello world";
...
ProkmemPtr<char> pStr(Str), tmp;
tmp = pStr + 11;
while(pStr  != tmp)
{
while(UCSRA & (1<<UDRE));
UDR = *pStr++;
}
При этом генерируется код аналогичный тому, что генерирует IAR при использовании указателей на __flash.
Теперь можно писать шаблонные функции работающие с любыми указателями:
Код
template<ctoss T>
void UsartPuts(T str)
{
while(char tmp = *str)
{
while(UCSRA & (1<<UDRE));
UDR = tmp;
str++;
}
...
// Отправляем строку из флеша
UsartPuts(ProkmemPtr<char>(Str));
// ... из оперативки.
UsartPuts("12345");
}
Таким образом можно реализовать указатели куда угодно, - во внутренний EEPROM, например, или даже во внешний последовательный. Можно сделать универсальный указатель, который помнит куда он указавает, во флеш или оперативку (в IAR такие тоже есть).

Единственное, что не умеет этот указатель в отличии от обычных, так это давать доступ к полям структуры (если это указатель на какую-то структуру) через оператор " -> ". Реализация этой функциональности потребует использования динамической памяти, что не всегда хорошо для АВРок.
0
mos80
0 / 0 / 0
Регистрация: 07.03.2010
Сообщений: 233
08.02.2011, 20:50 28
Цитата Сообщение от miyvir
Не прийдётся ничего дублировать. И макросами пользоваться здесь тоже не стоит. Описывать надо только уникальные отличия для разных камней. А выбирать нужный заголовок с этим описанием в системе сборки, в зависимости от типа процессора.
Зачем выбирать заголовок в ручную, если он определяется выбранным камнем (что указывается в make файле). Типовые либы решают это дефайнами.
0
miyvir
0 / 0 / 0
Регистрация: 27.06.2010
Сообщений: 405
08.02.2011, 23:08 29
А во что превращаются эти типовые либы, если параметр по которому идет выбор может принимать с десяток(и больше) параметров и используется для выбора десятка вариантов (возможно несвязанных) кода? Такая мешанина получается. Я это уже проходил. А когда еще несколько компиляторов нужно поддерживать...
Я из своей библиотеки "для портов" не просто так выпилил все ветвления по типу компилятора и типам МК.
0
08.02.2011, 23:08
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.02.2011, 23:08

«Шаблоны шаблонов» vs «шаблоны с параметрами-шаблонами».
«Шаблоны шаблонов» vs «шаблоны с параметрами-шаблонами». Есть ли разница в...

Шаблоны. Плохо понимаемые моменты из книги "Шаблоны С++. Справочник разработчика". (Вандевурд, Джосаттис)
Так как изучаю эту книгу, то в некоторых местах возникают вопросы. Чтобы не...

Помогите писать на С++ через шаблоны. Консуле я писал, но надо писать исползуя шаблоны
В одномерном массиве, состоящем из п вещественных элементов, вычислить: 1)...


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

Или воспользуйтесь поиском по форуму:
29
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru