crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> шаблоны, непонятные
Litkevich Yuriy
  опции профиля:
сообщение 9.12.2020, 11:48
Сообщение #1


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Столкнулся с таким кодом:
#define APBPERIPH_BASE        PERIPH_BASE
#define AHB2PERIPH_BASE       (PERIPH_BASE + 0x08000000)

#define GPIOA_BASE            (AHB2PERIPH_BASE + 0x00000000)
#define GPIOB_BASE            (AHB2PERIPH_BASE + 0x00000400)
//..


//    Непонятный код:

template<uint32_t> uint32_t getPeripheral();          ///< generic template - never used
template<> inline uint32_t getPeripheral<GPIOA_BASE>() { return RCC_AHBPeriph_GPIOA; }
template<> inline uint32_t getPeripheral<GPIOB_BASE>() { return RCC_AHBPeriph_GPIOB; }


Первая (непонятная) строка:
думаю, мне понятна - объявление шаблонной функции, у которой параметр шаблона имеет тип uint32_t, имя шаблонного параметра не указано, т.к. не используется (да и комментарий в коде говорит об этом).

Вторая (непонятная) и последняя строки:
тут совсем непонятно, т.к. вижу вначале ключевое слово template, а в конце фигурные скобки, то вроде это определение шаблонной функции.
Однако после имени функции идут фигурные скобки с неким содержимым, так обычно вызывают шаблонные функции.

Дак что же это в 2-ух последних строках?

напоминает перегруженные функции

Сообщение отредактировал Litkevich Yuriy - 9.12.2020, 11:50
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 10.12.2020, 8:09
Сообщение #2


фрилансер
******

Группа: Участник
Сообщений: 2939
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Litkevich Yuriy, это специализация шаблона функции

первая строка - как бы начало, от которого нужно будет отталкиваться компилятору при подборе наиболее подходящей специализации. Причём тело функции отсутствует, это лишь объявление (если перейти к аналогии простых функций)

вторая и третья строки - специализация функции для параметра типа uint32_t, указанного при инстанцировании шаблона, равного GPIOA_BASE и GPIOB_BASE соответственно

#include <iostream>

#define PERIPH_BASE 42

#define APBPERIPH_BASE        PERIPH_BASE
#define AHB2PERIPH_BASE       (PERIPH_BASE + 0x08000000)

#define GPIOA_BASE            (AHB2PERIPH_BASE + 0x00000000)
#define GPIOB_BASE            (AHB2PERIPH_BASE + 0x00000400)

template<uint32_t> uint32_t getPeripheral();          ///< generic template - never used
template<> inline uint32_t getPeripheral<GPIOA_BASE>() { return 111; }
template<> inline uint32_t getPeripheral<GPIOB_BASE>() { return 222; }

int main()
{
    std::cout<<"1: "<<getPeripheral<GPIOA_BASE>()<<'\n';
    std::cout<<"2: "<<getPeripheral<GPIOB_BASE>()<<'\n';
    
    //все остальные циферки - компилятор сумеет,
    //но линкер заругается. Нет тела функции
    //std::cout<<"3: "<<getPeripheral<7>()<<'\n';
    //std::cout<<"3: "<<getPeripheral<777>()<<'\n';

    return 0;
}


с моей точки зрения шаблоны тут вообще не нужны, можно обойтись енумклассом

#include <iostream>

#define PERIPH_BASE 42
#define APBPERIPH_BASE        PERIPH_BASE
#define AHB2PERIPH_BASE       (PERIPH_BASE + 0x08000000)
#define GPIOA_BASE            (AHB2PERIPH_BASE + 0x00000000)
#define GPIOB_BASE            (AHB2PERIPH_BASE + 0x00000400)

enum class e_GPIOX_BASE:uint32_t
{
    A=GPIOA_BASE,
    B=GPIOB_BASE,
};

int main()
{
    e_GPIOX_BASE base{};
    
    base=e_GPIOX_BASE::A;
    std::cout<<"1: "<<(uint32_t)base<<'\n';

    base=e_GPIOX_BASE::B;
    std::cout<<"2: "<<(uint32_t)base<<'\n';

    return 0;
}


или даже так
#include <iostream>

inline constexpr uint32_t PERIPH_BASE=42;

inline constexpr uint32_t APBPERIPH_BASE=PERIPH_BASE;
inline constexpr uint32_t AHB2PERIPH_BASE=(PERIPH_BASE + 0x08000000);

inline constexpr uint32_t GPIOA_BASE=(AHB2PERIPH_BASE + 0x00000000);
inline constexpr uint32_t GPIOB_BASE=(AHB2PERIPH_BASE + 0x00000400);

enum class e_GPIOX_BASE:uint32_t
{
    A=GPIOA_BASE,
    B=GPIOA_BASE,
};

int main()
{
    e_GPIOX_BASE base{};
    
    base=e_GPIOX_BASE::A;
    std::cout<<"1: "<<(uint32_t)base<<'\n';

    base=e_GPIOX_BASE::B;
    std::cout<<"2: "<<(uint32_t)base<<'\n';

    return 0;
}


Сообщение отредактировал Алексей1153 - 10.12.2020, 8:13
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 10.12.2020, 8:57
Сообщение #3


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Спасибо, Алексей!

(кнопки "Спасибо" почему-то нет)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 19.4.2024, 12:27