Перегруженная или шаблонная функция?
- Войдите на сайт для отправки комментариев
Втр, 21/04/2020 - 12:43
Добрый день.
Подскажите какую функцию лучше использовать перегруженную или шаблонную?
С перегруженными кода больно много получается, а шаблонные я не особо люблю, ну или как сказать.
Может кто по опыту своему знает?
В абстрактной задаче стоить применить ту функцию, которая больше нравится. Или монетку подкинуть.
Добрый день.
Подскажите какую функцию лучше использовать перегруженную или шаблонную?
С перегруженными кода больно много получается, а шаблонные я не особо люблю, ну или как сказать.
Может кто по опыту своему знает?
с шаблонными больше кода получается, чем с перегруженными. Ты лучше активнее используй default значения передаваемых параметров в перегруженных функциях и будет норм.
например:
Подскажите какую функцию лучше использовать перегруженную или шаблонную?
- Подскажите какой автомобиль выбрать - КАМАЗ самосвал или Мерседес SL родстер?
- А Вам, простите, девочку по набережной покатать или десять кубов навоза перевезти?
Поэтому ответ такой: когда нет никакой задачи, то не нужно использовать ни то, ни другое. А когда появится задача, то она сама подскажет.
- Подскажите какой автомобиль выбрать - КАМАЗ самосвал или Мерседес SL родстер?
- А Вам, простите, девочку по набережной покатать или десять кубов навоза перевезти?
Этт ща фсё нипрально, патаму и живём как быдло. Вот раньше девки и в КАМАЗы прыгали и навоз возили и дети нормальные были. А щас? Нищщая страна сабирает в нете деньги на операццию... Тьфу, блеееее.
Спасибо за совет DetSimen.
Случай если что следующий:
void coupArr(byte* array, int sizeArray) { sizeArray = sizeArray / array[0]; uint8_t buf[sizeArray]; for (uint8_t i = 0; i < sizeArray; i++) { buf[i] = array[i]; } for (uint8_t i = 0; i < sizeArray; i++) { array[i] = buf[(sizeArray - 1) - i]; } } void coupArr(bool* array, int sizeArray) { sizeArray = sizeArray / array[0]; bool buf[sizeArray]; for (uint8_t i = 0; i < sizeArray; i++) { buf[i] = array[i]; } for (uint8_t i = 0; i < sizeArray; i++) { array[i] = buf[(sizeArray - 1) - i]; } } long digByNum(bool* digits, int arraySize) { long number = 0; for (uint8_t i = 0; i < arraySize / sizeof(digits[0]); i++) { number += digits[i]; number *= 10; } number /= 10; return number; } long digByNum(uint8_t* digits, int arraySize) { long number = 0; for (uint8_t i = 0; i < arraySize / sizeof(digits[0]); i++) { number += digits[i]; number *= 10; } number /= 10; return number; } void numByDig(uint8_t data, uint8_t* array) { for (uint8_t i = 0; i < UINT8_MAX; i++) { array[i] = data % 10; data /= 10; if (data == 0) { return 0; } } } void numByDig(int data, uint8_t* array) { for (uint8_t i = 0; i < UINT8_MAX; i++) { array[i] = data % 10; data /= 10; if (data == 0) { return 0; } } } void numByDig(long data, uint8_t* array) { for (byte i = 0; i < UINT8_MAX; i++) { array[i] = data % 10; data /= 10; if (data == 0) { return 0; } } } void printlnArr(uint8_t* array, int sizeArr) { for (uint8_t i = 0; i < sizeArr / sizeof(array[0]); i ++) { Serial.println(array[i]); } } void printArr(uint8_t* array, int sizeArr) { for (uint8_t i = 0; i < sizeArr / sizeof(array[0]); i ++) { Serial.print(array[i]); Serial.print(' '); } } void printlnArr(bool* array, int sizeArr) { for (uint8_t i = 0; i < sizeArr / sizeof(array[0]); i ++) { Serial.println(array[i]); } } void printArr(bool* array, int sizeArr) { for (uint8_t i = 0; i < sizeArr / sizeof(array[0]); i ++) { Serial.print(array[i]); Serial.print(' '); } }Строки №№ 47, 57 и 67 это про что? С какого бодуна void-функция вздумала чего-то возвращать? Коронавирус подцепила?
Это просто для выхода из функции
void numByDig(uint8_t data, uint8_t* array) { for (uint8_t i = 0; i < UINT8_MAX; i++) { array[i] = data % 10; data /= 10; if (data == 0) { return; } } }Ну или так..
С возвращаемым значением? Оригинально :-)
void numByDig(uint8_t data, uint8_t* array) { for (uint8_t i = 0; i < UINT8_MAX; i++) { array[i] = data % 10; data /= 10; if (data == 0) { return; } } }Ну или так..
Вот так уж пойдёт
Ну или можно просто break применить
Строки №№ 47, 57 и 67 это про что? С какого бодуна void-функция вздумала чего-то возвращать? Коронавирус подцепила?
Да там вообще дичь написана. Обратите внимание на строку 2, как вычисляется кол-во элементов в массиве :)))) Слышал звон, называется...
Что касается сути вопроса - то в данном конкретном примере прям просятся шаблонные функции, имхо.
Строки №№ 47, 57 и 67 это про что? С какого бодуна void-функция вздумала чего-то возвращать? Коронавирус подцепила?
Да там вообще дичь написана. Обратите внимание на строку 2, как вычисляется кол-во элементов в массиве :)))) Слышал звон, называется...
Не, ну а как ещё?
не для себя же)
template <typename Temp> void coupArr (Temp *array, int size) { int count = size; for (int i = 0; i < size/2; i++) { Temp buff = array[i]; array[i] = array[--count]; array[count] = buff; } }Не совсем. Скажите - бывают массивы с отрицательным числом элементов? А вы в size пихаете int, который знаковый. Надо второй параметр типа size_t использовать, как минимум.
Что за size_t?
Тип данных такой.
Что за size_t?
Как уже ответили, это тип данных, но в данном контексте это СКОРЕЕ ВСЕГО троллинг.
Как уже ответили, это тип данных, но в данном контексте это СКОРЕЕ ВСЕГО троллинг.
тролинг - это использовать для размера структуры тип int
Может быть я не прав. Я сегодня впервые увидел size_t. Посмотрел в исходниках - #define __SIZE_TYPE__ long unsigned int. Подумал, что использовать long unsigned int для индекса массива на микропроцессоре - это перебор. Поэтому и написал "СКОРЕЕ ВСЕГО".
Или действительно "Надо второй параметр типа size_t использовать, как минимум."? Основной вопрос к "как минимум"
Посмотрел в исходниках - #define __SIZE_TYPE__ long unsigned int. Подумал, что использовать long unsigned int
Вы не туда посмотрели. Там много #if и Вы в них запутались. Напечатайте sizeof(size_t) и убедитесь в этом.
Вы не туда посмотрели. Там много #if и Вы в них запутались. Напечатайте sizeof(size_t) и убедитесь в этом.
Да вы правы. Для моего UNO значение sizeof(size_t) равно 2.
Но до этого меня заинтересовало - а может ли индекс массива быть отрицательный?
Нашел в инете, что может, проверил в ардуино. Компилируется и работает.
Сначала я думал в сторону - может ли быть отрицательное смещение относительно указателя? Вроде тоже может.
В принципе может, но Вы сами знаете куда этот путь ведёт.
Не может быть отрицательным только размер, указываемый при объявлении массива, а индекс - это же обыкновенная операция сложения, а операнду операции сложения никто ещё пока не запрещал быть отрицательным.
А почему нет? Это же на самом деле никакое не смещение (о чём прямо говорится в стандарте языка) - это просто арифметическая операция вычитания (или сложения с отрицательным) - какие проблемы, почему нет?
Но до этого меня заинтересовало - а может ли индекс массива быть отрицательный?
А я писал где-то про индекс? Я писал про РАЗМЕР массива. и тип данных size_t там - в самую дырочку.
А я писал где-то про индекс? Я писал про РАЗМЕР массива. и тип данных size_t там - в самую дырочку.
Это я просто расписывал "полет своей мысли". Постепенно в переписке я отдалился от начального поста.
Я писал, что воспринимаю это как троллинг (в данном контексте - т.е. в адрес новичка), т.к. объявление размера массива как size_t названо КАК МИНИМУМ НЕОБХОДИМЫМ условием.
Я писал, что воспринимаю это как троллинг (в данном контексте - т.е. в адрес новичка), т.к. объявление размера массива как size_t названо КАК МИНИМУМ НЕОБХОДИМЫМ условием.
Никакого троллинга, просто привычка к аккуратности. Есть старый холивар: кто должен заботиться о правильности переданных параметров - вызывающая сторона и вызываемая. Вопрос во многом философский, и тут не совсем уместен, однако в обсуждаемом случае - очевидно, что для аккуратности стоит использовать тот тип данных, который описывает размерность как мнемонически (size - понятно, что это размер), так и по определению, т.к. size_t - беззнаковый тип, а нулевая размерность массива, в отличие от отрицательной - вполне допустима.
Посмотрите для интереса - в STL всё, что касается размерностей - имеет тип size_t. Более того, оператор sizeof c C++ 11 возвращает размер, как тип std::size_t.
Так что - никакого троллинга.
Ещё более того: при описании массива, типа
<тип> massiv [<константа>];
константа всегда преобразуется к std::size_t, а если не может быть преобразована, то это синтаксическая ошибка.
Лично я узнал что то новое для себя читая этот пост. Но так и не могу понять "как минимум необходимым условием" чего это является. Может это позволит избежать ошибок? Написал простой пример типа
volatile int vInt=0, vInt1=0; int coupArr (size_t size) { cli(); // чтобы оптимизатор функцию не выкинул. sei(); return size; } vInt = -1; vInt1 = coupArr (vInt);Подумал - может компилятор ругнется на несоответствие типов. Нет не ругнулся. функция приняла -1 и вернула -1. Я не опытный пользователь Ардуино и С++. Может есть ключи компилятора при установке которых он будет показывать ошибки такого рода. Но я, как и все новички, использую настройки по умолчанию. Но даже если проверка и будет происходить, все равно при передаче в функцию указателей на массивы важно (наверное), чтобы передаваемый размер не выходил за границу массива. А это на этапе компиляции не всегда можно проверить. Поэтому и считаю это ТРЕБОВАНИЕ излишним для новичков.
Поэтому и считаю это ТРЕБОВАНИЕ излишним для новичков.
1. Я ничего не требовал;
2. Лучше сразу делать хорошо, херово - оно само получается.
А как сделать две разные шаблонные функции в одном файле?
template <typename T> void couppArr (T *Arrrray, int size) { int count = size; for (int i = 0; i < size / 2; i++) { T buff = arrrray[i]; arrrray[i] = arrrray[--count]; arrrray[count] = buff; } } void numByDig(T data, T *AArray) { for (uint8_t i = 0; i < UINT8_MAX; i++) { AArray[i] = data % 10; data /= 10; if (data == 0) { break; } } }Я пробовал так, ни катит.
и с двумя template <typename> тоже не получается
и с двумя template <typename> тоже не получается
В заголовочном файле шаблоны описаны? Давайте код, который "с двумя", и что говорит компилятор.
А Вы что, слово template экономите? Кончаются?
На каждую функцию своё слово template и делайте их хоть 100500.
А Вы что, слово template экономите? Кончаются?
На каждую функцию своё слово template и делайте их хоть 100500.
Всм?
и с двумя template <typename> тоже не получается
В заголовочном файле шаблоны описаны? Давайте код, который "с двумя", и что говорит компилятор.
Заголовочный файл (cpp нет):
#pragma once #include <Arduino.h> typedef enum {least, biggest} itemType ; #define printArr(x) printtArr((x), sizeof((x))) #define coupArr(v) couppArr((v), sizeof((v))) template <typename T> void couppArr (T *Array, int size) { int count = size; for (int i = 0; i < size / 2; i++) { T buff = array[i]; array[i] = array[--count]; array[count] = buff; } } template <typename TT> void numByDig(TT data, TT *array) { for (uint8_t i = 0; i < UINT8_MAX; i++) { array[i] = data % 10; data /= 10; if (data == 0) { break; } } } long digByNum(bool* digits, int arraySize) { long number = 0; for (uint8_t i = 0; i < arraySize / sizeof(digits[0]); i++) { number += digits[i]; number *= 10; } return number / 10; } long digByNum(uint8_t* digits, int arraySize) { long number = 0; for (uint8_t i = 0; i < arraySize / sizeof(digits[0]); i++) { number += digits[i]; number *= 10; } return number / 10; } uint8_t elementArr(uint8_t* array, int sizeArr, itemType typeElement) {if(typeElement == biggest) {byte largestElement = 0; for (byte i = 0; i < (sizeArr / array[0]); i ++) { if (array[i] > largestElement) largestElement = array[i]; } return largestElement; } } void printtArr(uint8_t* array, int sizeArr, bool ln = false) { if (!ln) { for (uint8_t i = 0; i < sizeArr / sizeof(array[0]); i ++) { Serial.print(array[i]); Serial.print(' '); } Serial.println(); } else { for (uint8_t i = 0; i < sizeArr / sizeof(array[0]); i ++) { Serial.println(array[i]); } } } void printtArr(bool* array, int sizeArr, bool ln = false) { if (!ln) { for (uint8_t i = 0; i < sizeArr / sizeof(array[0]); i ++) { Serial.print(array[i]); Serial.print(' '); } Serial.println(); } else { for (uint8_t i = 0; i < sizeArr / sizeof(array[0]); i ++) { Serial.println(array[i]); } } }Слова компилятора:
Arduino: 1.8.12 (Windows 7), Плата:"ATmega328 based, Old bootloader, External 16 MHz, GyverUART [Warning!], AVR-GCC v8.3.0 [Warning!], Enable [Default], Enable [Default], Disable, 2.7V [Default], Disable [Default]" In file included from S:\Users\AE0E~1\AppData\Local\Temp\arduino_modified_sketch_835342\sketch_apr26a.ino:1: S:\Users\�������� ����\Documents\Arduino\libraries\array_operation/Array_operation.h: In function 'void couppArr(T*, int)': S:\Users\�������� ����\Documents\Arduino\libraries\array_operation/Array_operation.h:12:14: error: 'array' was not declared in this scope T buff = array[i]; ^~~~~ S:\Users\�������� ����\Documents\Arduino\libraries\array_operation/Array_operation.h:12:14: note: suggested alternative: 'Array' T buff = array[i]; ^~~~~ Array exit status 1 Ошибка компиляции для платы ATmega328 based. Этот отчёт будет иметь больше информации с включенной опцией Файл -> Настройки -> "Показать подробный вывод во время компиляции"Ну, и при чём тут шаблон, если Вы в 9-ой строке пишете Array, а в 12-14 array? Шаблон-то чем виноват?
И, кстати, Вы сообщения компилятора-то читайте - там же прямо так и написано "
error:'array'was not declaredinthisscope". Что непонятно-то?И, да, просто кстати, такие конструкции, как у Вас в строке 12 в универсальных шаблонах не пишут, от слова никогда. Ворота тут как-то Пуха в это макал - вот здесь в "ой, блин №1" как раз эта самая ошибка и показана. Посмотрите.
просто кстати, такие конструкции, как у Вас в строке 12 в универсальных шаблонах не пишут, от слова никогда. Ворота тут как-то Пуха в это макал - вот здесь в "ой, блин №1" как раз эта самая ошибка и показана. Посмотрите.
Не совсем понял что за ошибка, и как писать надо?
просто кстати, такие конструкции, как у Вас в строке 12 в универсальных шаблонах не пишут, от слова никогда. Ворота тут как-то Пуха в это макал - вот здесь в "ой, блин №1" как раз эта самая ошибка и показана. Посмотрите.
Не совсем понял что за ошибка, и как писать надо?
Ключевое для понимания - "operator=", и его отсутствие в типе данных, определённом пользователем.
Не совсем понял что за ошибка, и как писать надо?
Ну, Вы ссылку-то посмотрели? Программу оттуда запустили? Ругань компилятора видели? Разобрались, чего ему не нравится? Остались вопросы? Или как?
Я не понимаю при чём здесь код из ссылки и как он мне поможет, я спрашивал как правильно написать вот эту конструкцию
template <typename T> void couppArr (T *array, int size) { int count = size; for (int i = 0; i < size / sizeof(array[0]); i++) { T buff = array[i]; array[i] = array[--count]; array[count] = buff; } } template <typename TT,typename TTR> void numByDig(TT data, TTR *array) { for (uint8_t i = 0; i < UINT8_MAX; i++) { array[i] = data % 10; data /= 10; if (data == 0) { break; } } } template <typename TTT> long digByNumm(TTT* digits, int arraySize) { long number = 0; for (uint8_t i = 0; i < arraySize / sizeof(digits[0]); i++) { number += digits[i]; number *= 10; } return number / 10; } template <typename TTTT> uint8_t itemmArr(TTTT* array, int sizeArr, itemType typeItem) { TTTT Item = array[0]; if (typeItem == biggest) { for (uint8_t i = 0; i < (sizeArr / array[0]); i ++) { if (array[i] > Item) Item = array[i]; } } else if(typeItem == least) { for (uint8_t i = 0; i < (sizeArr / array[0]); i ++) { if (array[i] < Item) Item = array[i]; } } return Item; }Я не понимаю при чём здесь код из ссылки и как он мне поможет, я спрашивал как правильно написать вот эту конструкцию
Какую конструкцию? Все 45 строк? Откуда мне знать как её писать правильно, если Вы не сказали что Вы собрались писать?
Я то Вам говорил о гораздо более локальной вещи. Перечитайте пост #41 - я говорил про одну строку (которую Вы так и не исправили. В Вашем нынешнем скетче в строках №№ 5 и 34 ровно та же самая ошибка.
Вот как раз с этой ошибкой Вам и поможет разобраться тот код по ссылке. Там она такая же. Если Вы там доберётесь до библиотеки qwonelib.h, то увидите в строке №20 ровно такую же конструкцию, как у Вас. И там Ворота привёл пример при котором всё это валится нахрен. Смотрите, изучайте, Я не могу изучить за Вас. я это и так знаю.