ViKo 1 9 декабря, 2019 Опубликовано 9 декабря, 2019 · Жалоба Вот, для обучения пробую создать такой шаблонный класс. Но не могу даже правильно написать. Помогите, где какую скобку и имя вставить. #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'); } Без конструктора оно легально? Мне, как бы, ни к чему. Мне только функции из него нужны. Но это вопрос другой. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 10 декабря, 2019 Опубликовано 10 декабря, 2019 · Жалоба Я не очень понял, что нужно. Просто комбинировать маски? Это просто: // шаблонная функция с одним параметром (она будет завершать рекурсию) 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; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 10 декабря, 2019 Опубликовано 10 декабря, 2019 · Жалоба 14 минут назад, AHTOXA сказал: Я не очень понял, что нужно. Просто комбинировать маски? Это просто пример, первое, что в голову пришло. Хочу класс иметь с разными функциями. Всё для портов STM32. Вот как эти рекурсивно компилирующиеся шаблоны вставить в класс? То есть, иметь шаблонные параметры класса, а использовать в его функциях. И в шаблон я передаю не типы, а значения. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 10 декабря, 2019 Опубликовано 10 декабря, 2019 · Жалоба Просто вокруг них написать class и поставить скобочки :-) Получится шаблонный класс (со своими параметрами, типа, номер порта), и внутри него шаблонные функции, со своими параметрами. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 10 декабря, 2019 Опубликовано 10 декабря, 2019 · Жалоба Не получается задать в шаблоне значения и по ним функции определять внутри класса. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 10 декабря, 2019 Опубликовано 10 декабря, 2019 · Жалоба #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. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 10 декабря, 2019 Опубликовано 10 декабря, 2019 · Жалоба Вы бы словами описали, что надо-то. А так - вот: 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; } Правда, я не понимаю, зачем тут класс, но раз надо, то пусть будет :-) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 10 декабря, 2019 Опубликовано 10 декабря, 2019 · Жалоба Словами: Тяну всё то же. Хочу сделать класс Port со всеми 16-ю битами, их режимами, инициализацией и управлением. Но чтобы можно было не только всеми 16-ю битами манипулировать, но и отдельными группами их - одиночными, парами, четверками, восьмерками (хватит для начала, а в идеале - любого количества). Предполагаю для такого класса в шаблоне задавать режимы всех битов, а для использования в группах иметь отдельные функции - члены класса. И в эти функции передавать параметры, заданные в шаблоне: имя порта, бит, тип входа-выхода, скорость, подтяжку, альт. функцию. При создании класса забить ему нужные режимы. В том же конструкторе. Причем, брать их из определения структур - свойств одиночных битов. Вопрос 1. Можно ли передать параметры шаблона класса в параметры шаблона функций этого класса? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 10 декабря, 2019 Опубликовано 10 декабря, 2019 · Жалоба Вопрос 2. portName не используется, зачем он? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 10 декабря, 2019 Опубликовано 10 декабря, 2019 · Жалоба 1 час назад, ViKo сказал: Вопрос 2. portName не используется, зачем он? Ну, я подозревал, что в шаблонных функциях он понадобится, вот и объявил. А как именно использовать - не знал. По остальному чуть позже отвечу. (Пока можете глянуть на вот эту мою заготовку). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 10 декабря, 2019 Опубликовано 10 декабря, 2019 · Жалоба Смотрю. Учусь по Вандервуду. Здесь компилирую. Отлично работает. https://www.onlinegdb.com/fork/BJA5GHO3N Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 10 декабря, 2019 Опубликовано 10 декабря, 2019 · Жалоба Я обычно проверяю мелкие вещи вот здесь: https://wandbox.org/ А если надо посмотреть дизассемблер разных компиляторов под разные архитектуры, то есть https://godbolt.org/ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 10 декабря, 2019 Опубликовано 10 декабря, 2019 · Жалоба 3 hours ago, ViKo said: При создании класса забить ему нужные режимы. В том же конструкторе. Причем, брать их из определения структур - свойств одиночных битов. Это будет не в стиле STL, т.е. не в стиле общепринятой архитектуры под C++ В стиле STL будет если создадите контейнер для пинов и создадите алгоритмы работы с контейнером пинов. Алгоритмы - это отдельные функции или объекты содержащие функции. А вставлять в один класс и хранилище пинов и алгоритмы работы с ними означает просто перемешать смыслы и получить дефицит имен. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 10 декабря, 2019 Опубликовано 10 декабря, 2019 · Жалоба 1 час назад, AlexandrY сказал: В стиле STL будет если создадите контейнер для пинов и создадите алгоритмы работы с контейнером пинов. Контейнер = объект (экземпляр). А так можно обойтись классами, без экземпляров. Для эмбеда это плюс. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 10 декабря, 2019 Опубликовано 10 декабря, 2019 · Жалоба 33 minutes ago, AHTOXA said: Контейнер = объект (экземпляр). А так можно обойтись классами, без экземпляров. Для эмбеда это плюс. Не, контейнер это специальный класс наделенный определенными свойствами характерными для "контейнеров" STL. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться