Перейти к содержанию
    

Нетиповой вариативный шаблон класса. Помогите написать.

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

#include <stdint.h>
#include <assert.h>

constexpr char S1 = 'A';
constexpr char S2 = 'B';
constexpr char S3 = 'C';

template <char First, char ... Other> class Pack
{
public:
	template <> static uint64_t comb(char First)
	{ return First << 8; }
	template <> static uint64_t comb(char ...)
	{ return (First << 8 | comb(Other ...)); }
};

int main(void)
{
	using P = Pack<S1,S2>;
	volatile uint64_t D = P::comb('D','E');
}

Без конструктора оно легально? Мне, как бы, ни к чему. Мне только функции из него нужны. Но это вопрос другой. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я не очень понял, что нужно.

Просто комбинировать маски? Это просто:

// шаблонная функция с одним параметром (она будет завершать рекурсию)
template <typename First>
uint32_t Comb(First value)
{
    return value;
}

// шаблонная функция с более чем одним параметром. Первый параметр 
// отделяется в First, остальные - упакованы в Other
template <typename First, typename... Other>
uint32_t Comb(First first, Other... other)
{
    return Comb(other...) << 8 | Comb(first);
}

// Применение:
std::cout << Comb('A', 'B', 'C') << std::endl;
std::cout << Comb(2, 1, 1) << std::endl;


// Для c++17 можно проще, через if constexpr:
template <typename First, typename... Other>
uint32_t CombC17(First first, Other... other)
{
	uint32_t value { 0 };
	if constexpr (sizeof...(Other) > 0)
	{
		value = CombC17(other...) << 8;
    }
    value |= first;
    return value;
}

// Примененять так же:
std::cout << CombC17('A', 'B', 'C') << std::endl;
std::cout << CombC17(2, 1, 1) << std::endl;

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

14 минут назад, AHTOXA сказал:

Я не очень понял, что нужно.

Просто комбинировать маски?

Это просто пример, первое, что в голову пришло. Хочу класс иметь с разными функциями. Всё для портов STM32.

Вот как эти рекурсивно компилирующиеся шаблоны вставить в класс?

То есть, иметь шаблонные параметры класса, а использовать в его функциях.

И в шаблон я передаю не типы, а значения.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Просто вокруг них написать class и поставить скобочки :-)

Получится шаблонный класс (со своими параметрами, типа, номер порта), и внутри него шаблонные функции, со своими параметрами.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

#include <stdint.h>
#include <assert.h>
#include <iostream>


constexpr char S1 = 'A';
constexpr char S2 = 'B';
constexpr char S3 = 'C';

template <typename First = char, typename ... Other> class Pack
{
public:
	template <First> static uint64_t comb(First value)
	{ return value << 8; }
	template <First, Other...> static uint64_t comb(First value, Other ... values)
	{ return (value << 8 | comb(values ...)); }
};


int main(void)
{
	using namespace std;
	// using P = Pack<S1,S2>;
	// Pack<char, char> P(S1, S2);
	// volatile uint64_t D = P::comb('D','E');
	Pack<char> P;
	std::cout << P.comb(S1, S2);
	// std::cout << Pack<char>.comb(S1, 'B', 'C') << std::endl;
}

Source/VariadicTemplate.cpp(44): error: no matching member function for call to 'comb'
        std::cout << P.comb(S1, S2);
                     ~~^~~~
Source/VariadicTemplate.cpp(30): note: candidate function template not viable: requires single argument 'value', but 2 arguments were provided
        template <First> static uint64_t comb(First value)
                                         ^
Source/VariadicTemplate.cpp(32): note: candidate function template not viable: requires single argument 'value', but 2 arguments were provided
        template <First, Other...> static uint64_t comb(First value, Other ... values)
                                                   ^
1 error generated.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы бы словами описали, что надо-то.

А так - вот:

template <char portLetter> class Port
{
public:
      static constexpr char portName { portLetter };
    
	template <typename First>
	static uint64_t comb(First value) { return value; }
	template <typename First, typename... Other>
	static uint64_t comb(First value, Other ... values) { return comb(values ...) << 8 | comb(value); }
};



int main()
{
	using PortA = Port<'A'>;
	std::cout << PortA::comb(1, 1, 1) << std::endl;
}

Правда, я не понимаю, зачем тут класс, но раз надо, то пусть будет :-)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Словами:

Тяну всё то же. Хочу сделать класс Port со всеми 16-ю битами, их режимами, инициализацией и управлением. Но чтобы можно было не только всеми 16-ю битами манипулировать, но и отдельными группами их - одиночными, парами, четверками, восьмерками (хватит для начала, а в идеале - любого количества). Предполагаю для такого класса в шаблоне задавать режимы всех битов, а для использования в группах иметь отдельные функции - члены класса. И в эти функции передавать параметры, заданные в шаблоне: имя порта, бит, тип входа-выхода, скорость, подтяжку, альт. функцию. 

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

Вопрос 1. Можно ли передать параметры шаблона класса в параметры шаблона функций этого класса?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вопрос 2. portName не используется, зачем он?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, ViKo сказал:

Вопрос 2. portName не используется, зачем он? 

Ну, я подозревал, что в шаблонных функциях он понадобится, вот и объявил. А как именно использовать - не знал.

По остальному чуть позже отвечу. (Пока можете глянуть на вот эту мою заготовку).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Смотрю. Учусь по Вандервуду.

Здесь компилирую. Отлично работает.

https://www.onlinegdb.com/fork/BJA5GHO3N

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я обычно проверяю мелкие вещи вот здесь: https://wandbox.org/

А если надо посмотреть дизассемблер разных компиляторов под разные архитектуры, то есть https://godbolt.org/

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 hours ago, ViKo said:

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

Это будет не в стиле STL, т.е. не в стиле общепринятой архитектуры под C++
В стиле STL будет если создадите контейнер для пинов и создадите алгоритмы работы с контейнером пинов.

Алгоритмы - это отдельные  функции или объекты содержащие функции. 

А вставлять в один класс и хранилище пинов  и алгоритмы работы с ними означает просто перемешать смыслы и получить дефицит имен.  
 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, AlexandrY сказал:

В стиле STL будет если создадите контейнер для пинов и создадите алгоритмы работы с контейнером пинов.

Контейнер = объект (экземпляр). А так можно обойтись классами, без экземпляров. Для эмбеда это плюс.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

33 minutes ago, AHTOXA said:

Контейнер = объект (экземпляр). А так можно обойтись классами, без экземпляров. Для эмбеда это плюс.

Не, контейнер это специальный класс наделенный определенными свойствами характерными для "контейнеров" STL.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...