Перегрузка функций
- Войдите на сайт для отправки комментариев
Пт, 12/03/2021 - 10:10
Сразу к делу:
class MyClass { public: void Func(boolean p1 = false); void Func(uint8_t p1, boolean p2 = false); }; void MyClass::Func(boolean p1) {} void MyClass::Func(uint8_t p1, boolean p2) {} MyClass Test; void setup() { Test.Func(true); Test.Func(1); } void loop() {}
Ясное дело в 15-16 имею ошибку ambiguous
Переделал так
enum MyBool {False = 0, True}; class MyClass { public: void Func(MyBool p1 = False); void Func(uint8_t p1, MyBool p2 = False); }; void MyClass::Func(MyBool p1) {} void MyClass::Func(uint8_t p1, MyBool p2) {} MyClass Test; void setup() { Test.Func(True); Test.Func(1); } void loop() {}
И собственно вопрос - Как сделать правильно? Без лишних приемов профи, а лаконично и надежно в моей ситуации?
По моему, с аргументами по умолчанию вы получаете одну и ту же функцию, с точки зрения компнилятора. Послежу за темой, интересно что великие скажут полезного
Подпишусь
А что говорит это:
Просто предположение...
Просто предположение...
Приведение к типу, конечно работает, просто мне визуально так не нравиться
А пожертвовать дефолтным значением p2 никак?
Визуально не нравится - суйте в функцию переменную соотв. типа.
Ибо:
Ясное дело в 15-16 имею ошибку ambiguous
ну оно же и вправду амбигоус, вы же сами понимаете
Каждый вариант функции должен иметь УНИКАЛЬНЫЙ набор параметров. Если наборы получаются похожими, можно ввести холостой парметр, который нужен только для различения вариантов функций:
либо убери default значения параметров. Совсем, оба.
либо убери default значения параметров. Совсем, оба.
Насколько я понимаю, для четкого определения достаточно убрать дефолт второго аргумента, а дефолт единственного параметра первой функции не помешает?
Насколько я понимаю, для четкого определения достаточно убрать дефолт второго аргумента
конечно.
Подойдет любое изменение заголовков, которое сделает два заголовка уникальными
Насколько я понимаю, для четкого определения достаточно убрать дефолт второго аргумента, а дефолт единственного параметра первой функции не помешает?
Да
Спасибо за отклик, в целом я так и думал. Видел с шаблонами заморочки, но для меня слишком заумно. Мне тогда проще создать функцию с другим именем, для редко используемого не дэфолтного состояния.
Ну, понятно, что вызов
не соответствует точно ни одной из перечисленных выше функций, т.к. 1 имеет тип int. Компилятор смотрит куда можно преобразовать и обнаруживает, что можно хоть в uint8_t, хоть в bool. Вот он и не может выбрать.
Решений миллион. Одно Вы привели сами. Другое (указать точный тип первого параметра) привел BOOM в #3. Все решения хорошие и правильные. Можно привести ещё десяток. Например, сделать первый параметр не uint8_t, а int - тогда совпадение типа будет точным и это будет более высокий приоритет, чем у преобразования в bool. Но это решение хуже, чем то, что привёл BOOM, т.к. будет дополнительный расход ресурсов на передачу двухбайтового значения, а оно там не нужно.
Если Вы эстет и параноидальный экономист ресурсов, то Вы можете поставить вопрос: а можно ли сделать, чтобы не писать (uint8_t) перед 1, но при этом не расходовать лишние ресурсы, как было с параметром типа int? Можно и так. Достаточно добавить ещё один inline метод вот так:
эта инлайн функция выродится в ноль (оптимизатор постарается) и расход ресурсов будет точно такой же, как в примере BOOM, только перед 1 ничего писать не надо.
Можно ещё десяток вариантов привести - все хорошие. Какой использовать - хозяин-барин, иногда есть доп. соображения по задаче. Главное, общее правило соблюдать - список параметров должен однозначно позволять выбрать правильную функцию.
Если хотите подробнее, читайте стандарт, там этому посвящено ажно более 30 страниц.
Спасибо, Евгений Петрович! Всегда с удовольствием читаю ваши образовательные посты!