EdgeAligned 83 23 июня Опубликовано 23 июня · Жалоба Говорят, даже на Питоне микроконтроллеры прогают. Я, правда, сам не пробовал. 55 минут назад, Arlleex сказал: А вот так уже работает Да, конкретные специализации шаблонов метода (или всего класса) уже можно перенести в .cpp. То есть, косяк в том, что имя типа шаблона не видно в файле .cpp. Хотя, если шаблонный метод вынести из класса, оставив в том же файле .hpp, то всё компилируется. Такой вот попандос. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 55 23 июня Опубликовано 23 июня · Жалоба 6 minutes ago, EdgeAligned said: а Питоне микроконтроллеры прогают Конечно. Причем без всего этого геморроя с шаблонами. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 23 июня Опубликовано 23 июня · Жалоба 2 часа назад, Arlleex сказал: Есть ли какой-то чисто практический пример, а не академический, когда указатели на методы или данные класса действительно лаконично решают задачу? Странный вопрос... Например - если имеется много переменных-членов, которые сами по себе независимы (логически), но в какой-то момент их нужно обработать однотипно, все сразу. Как быть в этом случае? Самое логичное и оптимальное: создать массив указателей на члены класса и с помощью него обработать. Например: В классе есть много разных указателей на объекты, созданные в динамической памяти (простые, без деструкторов). В деструкторе класса их нужно удалить. Вот с помощью массива указателей на члены класса это сделать удобно и оптимально. Другой вариант: На вход некоторой член-функции класса нужно подать const-массив, описывающий способ обработки чего-то. В этом массиве нужно сослаться на какие-то член-данные или методы класса. Здесь тоже нужны указатели на члены класса. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 23 июня Опубликовано 23 июня · Жалоба 34 minutes ago, jcxz said: с помощью массива указателей на члены класса .... самый "практический способ" выстрелить себе в ногу Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 178 24 июня Опубликовано 24 июня · Жалоба Возможно для однотипного изменения какого-то элемента в целом списке объектов, но когда заранее точно не известно, какой мембер надо менять. Чтобы кучу if() не писать, а возложить все на компилятор. В голову пример такой пришел. Есть панель с подсветкой, подсветка из отдельных управляемых RGB-светодиодов. Каждый диод описывается как class Led { public: u8 red, green, blue; ... }; И теперь в интерфейсе настройки подсветки есть ползунки изменения баланса синего, красного и зеленого (отдельно). Тянем красный - должны изменяться значения красного во всех диодах, и так для любых компонентов void changeBalance(Led leds[], u8 Led::*color, u8 value) { for (auto i = 0; i < MAX_LEDS_QNT; ++i) leds[i].*color = value; } Ну а в точке принятия решения, какой цвет будем менять u8 Led::*color; if (...) color = &Led::red; else if (...) color = &Led::green; else color = &Led::blue; u8 value = ...; // get_new_value() changeBalance(LedArray, color, value); В принципе, необходимость таких указателей понятна. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 17 24 июня Опубликовано 24 июня · Жалоба В 23.06.2024 в 20:31, Arlleex сказал: Я хотел, чтобы в заголовочнике был только "интерфейс" для быстрого охвата глазами. А в реализации уже потроха - туда смотреть не надо. I. Стандартный подход отделить мух от котлет через имплементарный заголовок с реализацией в файле myTemplate.h template <typename T> void f(T value); #include "myTemplateImpl.h" // Включаем реализацию здесь Файл myTemplateImpl.h template <typename T> void f(T value) { // Реализация функции } В этом случае мы отделяем объявление и определение шаблонной функции в разные файлы, но включаем файл с реализацией myTemplateImpl в конце файла с объявлением myTemplate.h. II. альтернативный подход Сделать инстанцировку в исходном файле. Файл myTemplate.h template <typename T> void f(T value); Файл myTemplate.cpp #include "myTemplate.h" template <typename T> void f(T value) { // Реализация функции } // Явная инстанцировка для нужных типов template void f<int>(int); template void f<double>(double); Использование #include "myTemplate.h" int main() { float a = 1.0f; double b = 3.14; f<float>(a); //для варианта II ошибка, т.к. нЭт его (нет инстанцировки для float в cpp) f<double>(b); //будет работать для обоих вариантов return 0; } 2 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 24 июня Опубликовано 24 июня · Жалоба 42 minutes ago, Arlleex said: В голову пример такой пришел. Если кроме хранения цвета класс Led больше ничего не делает, то достаточно его сделать просто структурой, а еще лучше union, чтобы была возможность менять как отдельно поля цветов, так и сразу все три цвета. Тогда не нужны такие крайне небезопасные способы обращения к полям и тем более их изменениям извне. Такие костыли с указателями на поля класса лишь демонстрируют что здесь в коде что-то не так, первый звоночек так сказать )) Или все же предполагается в будущем Led будет что-то еще и делать (хотя бы типа set/get)? Но тогда достаточно добавить соотв. методы в этот класс и заодно сделать класс наследником например итератора, дав ему еще больше возможностей для прохождения по списку объектов Led. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 178 24 июня Опубликовано 24 июня · Жалоба 1 час назад, juvf сказал: I. Стандартный подход Этот да, мне известен)) Цитата II. альтернативный подход Сделать инстанцировку в исходном файле. А этот я выше в своем же сообщении тоже выложил. Только маленький вопрос по синтаксису. Я писал template<> func<int>(int a) { } а Вы template func<int>(int a); т.е. без <> после ключевого слова template. Имеет ли это какое-то значение? Или это на уровне синтаксиса абсолютно ничего не значит? P.S. Не ну C++Вот так работает template<> func<int>(int a) { } вот так нет template func<int>(int a) { } вот так работает template func<int>(int a); вот так нет template<> func<int>(int a); 1 час назад, Forger сказал: Такие костыли с указателями на поля класса лишь демонстрируют что здесь в коде что-то не так, первый звоночек так сказать )) Это всего лишь пример, придуманный для мысленного представления как это можно было бы использовать на практике)) Не относитесь строго) Цитата Или все же предполагается в будущем Led будет что-то еще и делать (хотя бы типа set/get)? Как минимум, развивая идею с указателями на мемберы, нужно было упрятать цвета в private, а доступ к ним осуществлять через публичные сеттеры, и вот уже указателями на сеттеры можно было оперировать. Не стал писать так, чтобы упростить портянки примеров. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 17 24 июня Опубликовано 24 июня · Жалоба В 24.06.2024 в 13:15, Arlleex сказал: Имеет ли это какое-то значение? Или это на уровне синтаксиса абсолютно ничего не значит? имеет. тут стрельнуть себе в ногу можно... template<> func<int>(int a) { } //это явная специализация template func<int>(int a); // это явная инстанцировка в чем различие!? Когда нужно сделать отдельную реализацию для белой вороны какого-то типа, то делается явная специализация. поясню на примере Файл myTemplate.cpp #include "myTemplate.h" template <typename T> void f(T value) { // Общая реализация для всех типов } // Реализация явной специализации для типа `unsigned int` template <> void f<unsigned int>(unsigned int value) { printf("Hello unsigned int = %u"); } // Явная инстанцировка для нужных типов template void f<int>(int); template void f<double>(double); Использование #include "myTemplate.h" int main() { int a = -1; double b = 3.14; unsigned int c = 123; f<int>(a); // Использует общую реализацию f<double>(b); //Использует общую реализацию f<unsigned int>(c); //Использует специализированную реализацию, которая выводит "Hello unsigned int = *" return 0; } вобщем как-то так... 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 178 24 июня Опубликовано 24 июня · Жалоба 3 минуты назад, juvf сказал: template<> func<int>(int a) { } //это явная специализация template func<int>(int a); // это явная инстанцировка Не понятно тут только вот это. Это уже именно создание реального прототипа функции? Т.е. мы говорим компилятору - у нас где-то есть template. А ну-ка создай прототип шаблонной функции с таким-то типом. Так? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 17 24 июня Опубликовано 24 июня · Жалоба В 24.06.2024 в 13:54, Arlleex сказал: Т.е. мы говорим компилятору - у нас где-то есть template. А ну-ка создай прототип шаблонной функции с таким-то типом. Так? да. компилятор создаст вам функцию void f(int value) { // Общая реализация } В 02.06.2024 в 19:24, Arlleex сказал: В общем купил себе книжечку, толстееееннную)) а в этой книжке это не изложено? Или там нужно выкуривать эту инфу? ps так то конечно, лучше сразу получить знания на практике: есть практическая цель - есть вопрос: "а как это решить и в чем различие?". Чем курить книжку долгое время без практики. Все равно половину забудешь. Просто интересно, там это есть или нет? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 17 24 июня Опубликовано 24 июня · Жалоба В 23.06.2024 в 20:31, Arlleex сказал: Я хотел, чтобы в заголовочнике был только "интерфейс" для быстрого охвата глазами. А в реализации уже потроха - туда смотреть не надо. это не единственная причина убрать шаблон в cpp и сделать явную инстанцировку. Если реализовать шаблон полностью в *.h. (или в *.h и в *_impl.h), допустим потом если вызвать эту функцию f<int> 10 раз в одном файле, то компилятор встретив первый раз f<int>, сгенерирует код и после ужё встретив в этом файле f<int> компиялтор будет использовать уже сгенерированные код. Но если вы ещё в десяти файлах исходников вызовите f<int>, то компилятор будет гернерить код f<int> для каждого вашего *.cpp, где вы его вызовите. Один раз на каждый *.cpp где хоть раз есть вызов f<int>. Т.е. ваш main.o будет содержать отдельную f<int>, ваш noMain.o будет содержать отдельную f<int>, и все остальные объектники будет каждый содержать свой f<int>. Потом, при линковке, линкер выкинет все дубликаты и будет всего одна f<int> для всех. Если вы вынесете определение шаблона f<int> в *.cpp и сделаете явную инстанцировку, то при компиляции myTemplate.cpp и встетив строчку template void f<int>(int); у вас компиялтор сгенерирует f<int> в отдельный myTemplate.o . При компиляции остальных файлов *.срр генерации f<int> не будет. Получите myTemplate.0 с кодом f<int>. Линковщик потом свяжет весь проект. Итоговый код будет одинаковый в обоих случаях, но время компиляции уменьшится. У каждого метода есть ++ и --. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 178 24 июня Опубликовано 24 июня · Жалоба 45 минут назад, juvf сказал: а в этой книжке это не изложено? Или там нужно выкуривать эту инфу? Я ее пока что довольно выборочно читаю, поэтому возможно что пропустил. Хотя в предисловии там предупреждали, что книжечка расчитана на опытных в плюсах юзеров. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 83 24 июня Опубликовано 24 июня · Жалоба Кстати, насчет задания/изменения цвета. В этом плане удобно бывает оперировать не RGB, а HSV (HSB) моделью. То есть, оттенок-насыщенность-яркость. Цвет задается компонентой H в диапазоне 0 - 359, а яркость - компонентой V (L) в диапазоне 0 - 100. При значении компоненты S = 100 получаются чистые цвета. Если S = 0 получается белый цвет. Я использовал модель HSB для работы с эффектами на пиксельных светодиодах. То есть, все цветовые эффекты описывал в HSB, а перед загрузкой в линейки преобразовывал HSB -> RGB. 3 часа назад, Arlleex сказал: Не ну C++Вот так А я об этом раньше ведь говорил, но меня не понимали, говорили, что ++ это супер-круть типа и ваще. 🙂 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
razrab83 21 24 июня Опубликовано 24 июня · Жалоба 3 минуты назад, EdgeAligned сказал: говорили, что ++ это супер-круть типа и ваще. так и есть круть. 2 часа назад, Arlleex сказал: Я ее пока что довольно выборочно читаю, если что не понятно, спрашивайте. Столько интересного.... 😉 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться