Паттерны С++
От: LaptevVV Россия  
Дата: 24.06.25 06:34
Оценка: 14 (2)
https://cpppatterns.com/
Не только классические.
И по новым стандартам.
Например: https://cpppatterns.com/patterns/optional-arguments.html
Требуется С++17
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re: Паттерны С++
От: so5team https://stiffstream.com
Дата: 24.06.25 09:40
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>Например: https://cpppatterns.com/patterns/optional-arguments.html


Интересно, у вас специально получилось дать ссылку на крайне спорный паттерн?

This approach is more expressive than using pointers and nullptr.


Если брать пример использования:
  foo(5, std::nullopt, std::nullopt);

то это ничем не лучше:
  foo(5, nullptr, nullptr);


Выразительнее было бы что-то вроде:
  foo(5, no_f_specified, no_b_specified);

Где вместо `no_f_specified` и `no_b_specified` будут вменяемые, привязанные к прикладной области, именованные константы.
Вроде `default_scale` и `no_pretty_printing`:
  foo(5, default_scale, no_pretty_printing);


По поводу выразительности самой декларации:
void foo(int i,
         std::optional<double> f,
         std::optional<bool> b);

Тоже не однозначно, т.к. если придерживаться правила современного С++ о том, что голые указатели только невладеющие, то декларация:
void foo(int i,
         const double * f,
         const bool * b);

такая же понятная: качестве f и b допускается передача nullptr, если бы не допускалась, то вместо указателя была бы ссылка.

И еще вопрос о том, а что эффективнее -- передавать указатель на опциональный double или же std::optional для double. Ведь в C++ std::optional налагает плату в виде дополнительного bool-а, тем самым увеличивая размер параметра.

Однозначный выигрыш от std::optional есть когда мы передаем опциональный аргумент по значению, а не по ссылке/указателю. Что-то вроде:
struct MyData { ... };
struct ProcessingParams { ... };

void process(MyData what,
  // Принимаем по значению.
  std::optional<ProcessingParams> how) {...}

std::optional<ProcessingParams> // Возвращаем по значению.
try_find_custom_params() {...}

process(my_data, try_find_custom_params());


Вот в этом случае да, аргумент в виде optional удобнее, нежели указатель.
Но про такой сценарий по ссылке и не сказано
Re[2]: Паттерны С++
От: andrey.desman  
Дата: 24.06.25 09:54
Оценка:
Здравствуйте, so5team, Вы писали:

S>

This approach is more expressive than using pointers and nullptr.


S>Если брать пример использования:

S>
S>  foo(5, std::nullopt, std::nullopt);
S>

S>то это ничем не лучше:
S>
S>  foo(5, nullptr, nullptr);
S>


Можно писать
foo(5, {}, {});

но эт вкусовщина.

А "паттерн", да, кривой и вообще не паттерн.
optional подходит если нет особенного значения типа nullptr, 0, -1, пустой строки и т.д. То есть, эти значения тоже являются значениями, и
foo(5, nullptr, nullptr) не эквивалентно foo(5, {}, {})


Иначе зачем он нужен?... Шляпа.
Re: Паттерны С++
От: rg45 СССР  
Дата: 24.06.25 10:23
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>Например: https://cpppatterns.com/patterns/optional-arguments.html


   foo(5, 1.0, true);
   foo(5, std::nullopt, true);
   foo(5, 1.0, std::nullopt);
   foo(5, std::nullopt, std::nullopt);


Не читабельно совсем.

Как вариант:

#include <optional>

struct foo_options
{
   std::optional<double> f;
   std::optional<bool> b;
};

void foo(int, foo_options = {});

int main()
{
   foo(5, {.f = 1.0, .b = true});
   foo(5, {.f = 1.0});
   foo(5, {.b = true});
   foo(5);
}
--
Справедливость выше закона. А человечность выше справедливости.
Re[2]: Паттерны С++
От: LaptevVV Россия  
Дата: 24.06.25 10:54
Оценка:
LVV>>Например: https://cpppatterns.com/patterns/optional-arguments.html
S>Интересно, у вас специально получилось дать ссылку на крайне спорный паттерн?
Вот и обсуждение началось!
Прекрасно!
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re: Паттерны С++
От: B0FEE664  
Дата: 24.06.25 14:36
Оценка: 3 (1) +3
Здравствуйте, LaptevVV, Вы писали:

LVV>https://cpppatterns.com/

LVV>Не только классические.

По большей части это не паттерны, а приёмы/идиомы на С++, причём для начинающих.
Очень много чего нет:
например: signal-slot паттерн (который не Qt), потокобезопасная очередь, да даже factory отсутствует...
И каждый день — без права на ошибку...
Re[2]: Паттерны С++
От: sergii.p  
Дата: 24.06.25 17:12
Оценка:
Здравствуйте, so5team, Вы писали:

можно накрутить с variant и ignore, получается вроде как более читабельно

void foo(std::variant<decltype(std::ignore), int> fst, decltype(std::ignore), float> snd);

...

foo(std::ignore, 1.0);
foo(1, std::ignore);


хотя я предпочитаю заводить новые типы и у них уже добавлять значение по умолчанию

enum class NewType1 {Default = -1, Empty = -1};
enum class NewType2 {Default = -1, Empty = -1};

void foo(NewType1 fst, NewType2 snd);

foo(NewType1{1}, NewType2::Default);
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.