Re[12]: Box2D
От: so5team https://stiffstream.com
Дата: 05.07.18 11:20
Оценка: +1
Здравствуйте, lpd, Вы писали:

Про type-safe union разговор закрыли за невозможностью получить оный без шаблонов, правильно?

lpd>Писать код чтобы продемонстрировать полиморфизм, и его отличия от шаблонов?


Нет, просто чтобы можно было сопоставить два листинга рядом и увидеть разницу.

S>>Т.е. мы создаем result в динамической памяти? Дергаем хип и создаем лишнюю косвенность там, где можно было обойтись передачей/перемещением значения.


lpd>Ну все, фанатика move-семантики я переубедить не берусь.


Когда сказать нечего начинают ярлыки развешивать.

lpd>В каждом конкретном случае такую проблему можно решить без умных указателей — вариантов решений много, включая подсчет ссылок.


Во-первых, подсчет ссылок -- это уже умные указатели и есть.
Во-вторых, изначально речь шла про unique_ptr, который, в обычных случаях (т.е. со штатным deleter-ом), стоит столько же, сколько обычный голый указатель, и не требует ручного контроля за временем жизни. Но у вас же какие-то религиозные предубеждения против шаблонов и умных указателей. Потому остается закатывать Солнце вручную.

Простите, но с такими взглядами можно было программировать где-то до 1994-1995-х годов. С тех пор уже больше 20 лет прошло. Пора уже научиться пользоваться благами цивилизации.
Re[10]: Templates
От: chaotic-kotik  
Дата: 05.07.18 12:02
Оценка:
Здравствуйте, night beast, Вы писали:

NB>и чем замена ссылки на вариант лучше исходного кода? (кроме добавления лишнего мува)


Тем что можно вынести реализацию в cpp, лишнего мува там вроде нет, когда ты вызываешь к-тор reply_t, тебе нужно использовать move, без него будет копирование.
Вариант с variant в к-торе будет выглядеть так же, в точке использования, так как к-тор std::variant не помечен как explicit. Т.е. и там и там будет reply_t foo(std::move(value));
Re[11]: Templates
От: night beast СССР  
Дата: 05.07.18 12:09
Оценка:
Здравствуйте, chaotic-kotik, Вы писали:

NB>>и чем замена ссылки на вариант лучше исходного кода? (кроме добавления лишнего мува)


CK>Тем что можно вынести реализацию в cpp, лишнего мува там вроде нет, когда ты вызываешь к-тор reply_t, тебе нужно использовать move, без него будет копирование.


с чего бы вдруг? там передача по ссылке.

CK>Вариант с variant в к-торе будет выглядеть так же, в точке использования, так как к-тор std::variant не помечен как explicit. Т.е. и там и там будет reply_t foo(std::move(value));


и потом этот variant будет муваться в член класса. итого 2 мува.
Re[10]: Templates
От: chaotic-kotik  
Дата: 05.07.18 12:11
Оценка: +1
Здравствуйте, so5team, Вы писали:

S>Здравствуйте, chaotic-kotik, Вы писали:


CK>>мой вариант он проигнорировал, так что, делаем выводы


S>А разве был какой-то вариант? Передача std::variant прямо в конструктор reply -- это так себе выбор. Поскольку хранение result-а именно в виде variant -- это, по сути, деталь реализации reply_t. Не есть хорошо, что эта деталь уже торчит наружу. Но прибивать к ней гвоздями еще и конструктор reply... Кому как, короче говоря.


У тебя весь код живет в hpp, т.е. наружу торчит вообще все. Т.е. представить что код, использующий reply_t не знает про std::variant — невозможно.
std::variant — штука из стандартной библиотеки, не вижу особой проблемы в том, чтобы передавать его. Ты же не пытаешься спрятать std::string как деталь реализации?

S>Этот пример достаточно компактен и понятен. Как раз то, что нужно для ленивого обсуждения на форуме. И то, даже аналог этого простого случая никто вменяемо не без шаблонов переписать не смог (ну нельзя же вот это
Автор: alpha21264
Дата: 04.07.18
воспринимать всерьез).


Даже у этого примера есть преимущество перед твоим. Он будет работать везде. Твой вызовет проблемы даже на некоторых х86 дистрибутивах linux (c gcc 4.x), не говоря уже про всякие контроллеры.
Re[12]: Templates
От: chaotic-kotik  
Дата: 05.07.18 12:17
Оценка:
Здравствуйте, night beast, Вы писали:

CK>>Тем что можно вынести реализацию в cpp, лишнего мува там вроде нет, когда ты вызываешь к-тор reply_t, тебе нужно использовать move, без него будет копирование.


NB>с чего бы вдруг? там передача по ссылке.


у std::variant есть к-тор с perfect forwarding — https://en.cppreference.com/w/cpp/utility/variant/variant (номер 4)

NB>и потом этот variant будет муваться в член класса. итого 2 мува.


о ужас!
Re[11]: Templates
От: so5team https://stiffstream.com
Дата: 05.07.18 12:25
Оценка:
Здравствуйте, chaotic-kotik, Вы писали:

S>>А разве был какой-то вариант? Передача std::variant прямо в конструктор reply -- это так себе выбор. Поскольку хранение result-а именно в виде variant -- это, по сути, деталь реализации reply_t. Не есть хорошо, что эта деталь уже торчит наружу. Но прибивать к ней гвоздями еще и конструктор reply... Кому как, короче говоря.


CK>У тебя весь код живет в hpp, т.е. наружу торчит вообще все. Т.е. представить что код, использующий reply_t не знает про std::variant — невозможно.


Не нужно выдавать свои проблемы с фантазией за объективные факторы:
class reply_t final {
  ...
  std::variant<successful_result_t, failed_result_t> result_;
public:
  ...
  bool successful() const noexcept { return std::holds_alternative<successful_result_t>(result_); }

  template<typename L>
  decltype(auto) on_success(L handler) const {
    return handler(std::get<successful_result_t>(result_));
  }

  bool failed() const noexcept { return std::holds_alternative<failed_result_t>(result_); }
  ...
};
...
auto reply = receive_reply();
if(reply.successful())
  return reply.on_success([](const auto & d) {...});
else ...

То, что все это в hpp-файле не играет никакой роли, когда речь заходит о публичных и приватных полях/методах класса.

CK>Даже у этого примера есть преимущество перед твоим. Он будет работать везде.


Будет ли он работать -- это еще вопрос прямизны рук разработчика.

CK>Твой вызовет проблемы даже на некоторых х86 дистрибутивах linux (c gcc 4.x), не говоря уже про всякие контроллеры.


Ну что поделать, придется кросскомпиляцией заниматься.
Re[13]: Templates
От: night beast СССР  
Дата: 05.07.18 12:36
Оценка:
Здравствуйте, chaotic-kotik, Вы писали:

NB>>с чего бы вдруг? там передача по ссылке.


CK>у std::variant есть к-тор с perfect forwarding — https://en.cppreference.com/w/cpp/utility/variant/variant (номер 4)


и?

NB>>и потом этот variant будет муваться в член класса. итого 2 мува.


CK>о ужас!


я тебе просто показал, откуда дополнительный мув взялся
Re[12]: Templates
От: chaotic-kotik  
Дата: 05.07.18 12:42
Оценка: +1
Здравствуйте, so5team, Вы писали:


S>Не нужно выдавать свои проблемы с фантазией за объективные факторы:

S>
class reply_t final {
S>  ...
S>  std::variant<successful_result_t, failed_result_t> result_;
S>public:
S>  ...
S>  bool successful() const noexcept { return std::holds_alternative<successful_result_t>(result_); }

S>  template<typename L>
S>  decltype(auto) on_success(L handler) const {
S>    return handler(std::get<successful_result_t>(result_));
S>  }

S>  bool failed() const noexcept { return std::holds_alternative<failed_result_t>(result_); }
S>  ...
S>};
S>...
S>auto reply = receive_reply();
S>if(reply.successful())
S>  return reply.on_success([](const auto & d) {...});
S>else ...

S>То, что все это в hpp-файле не играет никакой роли, когда речь заходит о публичных и приватных полях/методах класса.

ты хочешь сделать вид, что в месте вызова on_success <variant> не подключен?

S>Ну что поделать, придется кросскомпиляцией заниматься.


занимался ли ты на практике чем-то подобным? так чтобы с зависимостями и сборкой пакетов под разные дистрибутивы?
Re[14]: Templates
От: chaotic-kotik  
Дата: 05.07.18 12:44
Оценка:
Здравствуйте, night beast, Вы писали:


NB>я тебе просто показал, откуда дополнительный мув взялся


я не распарсил, думал что ты имеешь ввиду что в первом случае std::move для параметра использовать не нужно
и что передается по ссылке?
Re[15]: Templates
От: night beast СССР  
Дата: 05.07.18 12:47
Оценка:
Здравствуйте, chaotic-kotik, Вы писали:

NB>>я тебе просто показал, откуда дополнительный мув взялся


CK>я не распарсил, думал что ты имеешь ввиду что в первом случае std::move для параметра использовать не нужно

CK>и что передается по ссылке?

в исходном коде мув один. в твоем -- два (один неявный)
Re[13]: Templates
От: so5team https://stiffstream.com
Дата: 05.07.18 12:49
Оценка:
Здравствуйте, chaotic-kotik, Вы писали:

CK>ты хочешь сделать вид, что в месте вызова on_success <variant> не подключен?


Может пора дурочку выключить? Если вам действительно что-то непонятно про разницу в использовании некоторого типа A в реализации некоторого типа B, и в интерфейсе этого типа B, то спросите что именно непонятно.

Или для вас принципиально то, чтобы в заголовочном файле с определением reply_t вообще из стандартных заголовочных файлов ничего не было подключено (т.е., чтобы pimpl во все поля)? Тогда ваша же идея на счет использования std::variant прямо в конструкторе оказывается несостоятельна. Вы уж определитесь.

S>>Ну что поделать, придется кросскомпиляцией заниматься.


CK>занимался ли ты на практике чем-то подобным? так чтобы с зависимостями и сборкой пакетов под разные дистрибутивы?


Что вы тянете, сразу длину в сантиметрах пишите. Ну или в миллиметрах, чтобы еще солиднее было.
Re[16]: Templates
От: alpha21264 СССР  
Дата: 05.07.18 13:04
Оценка: +1
Здравствуйте, so5team, Вы писали:


A>>Там не было желания общаться конструктивно.


S>По вашим сообщениям с фразами "Сам дурак" и "Ну это я прикололся" было заметно, что у вас нет желания общаться конструктивно.


"Сам дурак" произносится, когда сначала было слово "Дурак".
Да, фейспалм — это тоже "Дурак".

A>>>>Давай рассказывай, почему в данном случае нельзя обойтись одним битом вместо всех наворотов.


A>>Я сделаю вот так:

A>>
A>>struct result_t {
A>>   bool successful ;
A>>   A a_;
A>>   B b_;
A>>   C c_;
A>>   D d_;
A>>   E e_;
A>>// Конструктор/деструктор и пр. лабуда.
A>>};
A>>


S>Ожидаемо. Сейчас даже не будем говорить за оверхед по памяти/времени, т.к. в данном конкретном случае это не существенно.

S>Как вы собираетесь обеспечить гарантии того, что в случае неудачного результата программист не будет обращаться к полям a_, b_ и c_.

Ремнём по жопе. Этот способ всегда работает.
Есть другой способ — присваивать данным осмысленные значения даже в случае неуспеха
(например пустые массивы, нулевые строки и т.п.).
И пусть обращается. Программа продолжит работать. И даже правильно.
И даже не нужна специальная обработка ошибок.

Кстати, по поводу оверхеда. По моему опыту у темплейтов оверхеда больше.
Потому что копи-пастинг со всеми вытекающими.

S>Ну а тема дальнейшего расширения набора результатов в вашем подходе вообще открывает какие-то бездны фейспалма.


Сам дурак (это Вам за фейспалм).
В данном случае результат может быть либо успешный, либо неуспешный.
Какое тут расширение? Зачем?
Вы вообще, попробуйте сформулировать, что такое "результат",
и зачем Вы на каждый новый результат новый тип плодите.

A>>А если совсем-совсем жалко места (ну это совсем скупердяем надо быть) мы умеем использовать слово union.


S>Судя по тому, что вы уже написали, вы вряд ли можете что-то использовать что-то сложнее bool-а и int-а.


Опять хамите, а потом удивляетесь, что сам дурак. — Сам дурак.

A>>Поэтому мне не нужно решать тех проблем, которые есть в случае с темплейтами.


S>И какие же это проблемы?


Ну очевидно же — расплодили типов на ровном месте.

A>>Зачем Вы опять делаете навороты на ровном месте?!


S>Это не навороты. Это опыт. Не только наш.


Это ненужные навороты. Так говорит опыт. И не только наш.

Течёт вода Кубань-реки куда велят большевики.
Re[17]: Templates
От: so5team https://stiffstream.com
Дата: 05.07.18 13:23
Оценка:
Здравствуйте, alpha21264, Вы писали:

A>Да, фейспалм — это тоже "Дурак".


Вы сначала разберитесь кто вам фейспалмы показывает, а потом "Дураками" раскидывайтесь. А то ведь складывается впечатление, что вы с кем-то другим пытаетесь говорить.

A>Ремнём по жопе. Этот способ всегда работает.


Очевидно недостаточно, раз столько багов в софте. Или в вашем софте багов нет?

A>Есть другой способ — присваивать данным осмысленные значения даже в случае неуспеха

A>(например пустые массивы, нулевые строки и т.п.).

Вы представляете, а при использовании sum types (это которые и есть std::variant) этого делать не нужно. Прогресс таки не стоит на месте.

A>И пусть обращается. Программа продолжит работать. И даже правильно.


Это сейчас больше на молитвы похоже.

A>Кстати, по поводу оверхеда. По моему опыту у темплейтов оверхеда больше.

A>Потому что копи-пастинг со всеми вытекающими.

Это у вас представления о шаблонах из начала 90-х. Но в вашу криокамеру, наверное, ничего нового не попадает.

A>В данном случае результат может быть либо успешный, либо неуспешный.


Это вам так кажется.

A>Ну очевидно же — расплодили типов на ровном месте.


По сравнению с перечислением вообще всех полей в одном месте -- это не то, что не проблема, это даже не мелкие неприятности.

A>Это ненужные навороты. Так говорит опыт. И не только наш.


Судя по коду из начала 90-х у вас и опыт оттуда же. Между тем в мире нового опыта накоплено масса. На основании которого делают folly::Expected, boost::outcome и предложения по добавлению дешевых исключений в C++. Казалось бы с чего бы это?
Re[14]: Templates
От: chaotic-kotik  
Дата: 05.07.18 13:53
Оценка:
Здравствуйте, so5team, Вы писали:


S>Может пора дурочку выключить? Если вам действительно что-то непонятно про разницу в использовании некоторого типа A в реализации некоторого типа B, и в интерфейсе этого типа B, то спросите что именно непонятно.


У меня в проекте тысячи единиц трансляции, допустим этот класс reply_t должен использоваться в десяти, от которых зависит еще 100, я подключаю reply.h с этим классом, а там — #include <variant>, соответственно, все это добро подключается в 100 разных единиц трасляции. При этом совершенно фиолетово где используется variant, в реализации, или в реализации и интерфейсе.

S>Или для вас принципиально то, чтобы в заголовочном файле с определением reply_t вообще из стандартных заголовочных файлов ничего не было подключено (т.е., чтобы pimpl во все поля)? Тогда ваша же идея на счет использования std::variant прямо в конструкторе оказывается несостоятельна. Вы уж определитесь.


Мне принципиально называть вещи своими именами. Не важно, где используется шаблон. Зависимость это зависимость. По этому, с моей точки зрения, мой вариант лучше, т.к. он позволяет уменьшить reply.h, спрятав часть кода в cpp файл.

Если бы я писал этот класс для своего текущего проекта, ***_result_t были бы наследниками абстрактного класса и в реализации класса был бы уникальный указатель на base_result_t вместо variant. Это позволило бы, например, иметь реализации base_result_t отличные от failure_result_t и success_result_t, причем даже такие, о которых "знает" только какой-то один компонент. Можно было бы поменять реализацию без перекомпиляции сотни единиц трансляции, которые зависят от reply_t.

S>Что вы тянете, сразу длину в сантиметрах пишите. Ну или в миллиметрах, чтобы еще солиднее было.


С восхищением смотрю на людей, успешно что-то кросс-компилирующих, особенно в нетривиальных случаях. Я ни разу не смог настроить CI так, чтобы без докера и отдельных серверов с ARM и Solaris для сборки под ARM и Solaris.
Re[15]: Templates
От: so5team https://stiffstream.com
Дата: 05.07.18 14:03
Оценка: +1
Здравствуйте, chaotic-kotik, Вы писали:

CK>У меня в проекте тысячи единиц трансляции, допустим этот класс reply_t должен использоваться в десяти, от которых зависит еще 100, я подключаю reply.h с этим классом, а там — #include <variant>, соответственно, все это добро подключается в 100 разных единиц трасляции. При этом совершенно фиолетово где используется variant, в реализации, или в реализации и интерфейсе.


Если определение одного типа сказывается на таком количестве единиц трансляции, то у вас проблемы и без шаблонов.
Ну и ваш вариант с передачей std::variant в конструктор напрямую здесь ничего не исправит.

CK>Мне принципиально называть вещи своими именами. Не важно, где используется шаблон. Зависимость это зависимость. По этому, с моей точки зрения, мой вариант лучше, т.к. он позволяет уменьшить reply.h, спрятав часть кода в cpp файл.


Вы сейчас точно в трезвом уме? Предлагаемый вами вариант выглядел бы так:
struct reply_t {
  using result_t = std::variant<successful_result_t, failed_result_t>;
  ...
  result_t result_;

  reply_t(request_id_t id, worker_id_t id, result_t result);
};

И ничего бы вы с "зависимостью" от std::variant не сделали бы.

CK>Если бы я писал этот класс для своего текущего проекта, ***_result_t были бы наследниками абстрактного класса и в реализации класса был бы уникальный указатель на base_result_t вместо variant. Это позволило бы, например, иметь реализации base_result_t отличные от failure_result_t и success_result_t, причем даже такие, о которых "знает" только какой-то один компонент. Можно было бы поменять реализацию без перекомпиляции сотни единиц трансляции, которые зависят от reply_t.


Да, если бы были сотни единиц трансляции, вам было бы пофигу на возможных наследников base_result_t и полноту обработки этих наследников, тогда да, можно было бы и без шаблонов. По счастью, у нас другая ситуация.
Re[16]: Templates
От: chaotic-kotik  
Дата: 06.07.18 07:56
Оценка:
Здравствуйте, so5team, Вы писали:

S>Если определение одного типа сказывается на таком количестве единиц трансляции, то у вас проблемы и без шаблонов.

S>Ну и ваш вариант с передачей std::variant в конструктор напрямую здесь ничего не исправит.

Я не утверждал что он исправит. Поинт был в том, что зависимость есть зависимость и если используешь шаблоны, то приходится размещать код в hpp файлах, а значит увеличивать количество зависимостей и связность, даже если зависимости в реализации, а не в интерфейсе.
Для твоей библиотеки (ссылка выше была), это в общем-то и не проблема. Если бы мне нужно было использовать ее в своем big-ass проекте, я бы просто подключил ее в одном срр и показал наружу какой-нибудь удобный мне интерфейс. Но вот для вещей, которые активно используются внутри проекта практически везде, мы так не делаем. Вот открыл сейчас хедер в рабочем проекте, а там первые 200 строк вот такого:

namespace Foo {
namespace Bar { class A; class B; }
namespace Buzz { 
    class C;
    ...
}
}


и на ревью, если ты что-то изменил в хедере, у тебя первым делом спросят — а можно ли было обойтись без этого изменения?

S>Вы сейчас точно в трезвом уме? Предлагаемый вами вариант выглядел бы так:

S>
struct reply_t {
S>  using result_t = std::variant<successful_result_t, failed_result_t>;
S>  ...
S>  result_t result_;

S>  reply_t(request_id_t id, worker_id_t id, result_t result);
S>};

S>И ничего бы вы с "зависимостью" от std::variant не сделали бы.

Я этот код воспринял как toy example, честно говоря. Если это буквально вся реализация reply_t, то я ничего не менял бы.
Re[17]: Templates
От: so5team https://stiffstream.com
Дата: 06.07.18 08:06
Оценка:
Здравствуйте, chaotic-kotik, Вы писали:

CK>Для твоей библиотеки (ссылка выше была), это в общем-то и не проблема. Если бы мне нужно было использовать ее в своем big-ass проекте, я бы просто подключил ее в одном срр и показал наружу какой-нибудь удобный мне интерфейс. Но вот для вещей, которые активно используются внутри проекта практически везде, мы так не делаем. Вот открыл сейчас хедер в рабочем проекте, а там первые 200 строк вот такого:


Очень и очень хрупкий подход, особенно для кодовых баз, которые живут и активно эволюционируют больше 5 лет.

Но если компиляция занимает часы, то альтернативы придумать не так уж и просто.

CK>Я этот код воспринял как toy example, честно говоря.


Не совсем. Это кусочек из маленького proof-of-concept проекта объемом в 1.5KLOC. На таких масштабах выводить иерархию result-ов -- это оверкилл. Даже если объем этого проекта увеличится в 100 раз, то и в этом случае проблем с шаблонами быть не должно.
Re[17]: Templates
От: night beast СССР  
Дата: 06.07.18 08:10
Оценка:
Здравствуйте, chaotic-kotik, Вы писали:

CK>Для твоей библиотеки (ссылка выше была), это в общем-то и не проблема. Если бы мне нужно было использовать ее в своем big-ass проекте, я бы просто подключил ее в одном срр и показал наружу какой-нибудь удобный мне интерфейс. Но вот для вещей, которые активно используются внутри проекта практически везде, мы так не делаем. Вот открыл сейчас хедер в рабочем проекте, а там первые 200 строк вот такого:


CK>namespace Foo {
CK>namespace Bar { class A; class B; }
CK>}


интрузивные умные указатели используются?
Re: Templates
От: vopl Россия  
Дата: 06.07.18 08:19
Оценка:
Здравствуйте, smeeld, Вы писали:

S>Заметил, что у большинства практикующих C++ достаточно негативное отношение к шаблонам в CPP. Речь идёт не о использовании std или boost, которые состоят из таковых процентов на 80, а о написании кода с активным применением параметризации функций и типов. Это многими считается чуть ли не признаком недостатка квалификации, типа матёрый плюсовик всегда найдёт способ расписать без создания параметризованных типов, и вообще найдёт способ писать на C++ как можно проще. Это вообще что такое? Если принять это мнение за справедливое, то получается, что std и boost писали джуны несмышлённые и не знающие как просто писать на CPP?


В соседней теме вести с полей о потенциальных нововведениях в c++20, и там довольно много всяких страшных слов для "шаблонных хейтеров" , выделю наиболее ужасные на мой взгляд:

Контракты и друзья
Концепты (без друзей)
Что нового можно писать в шаблонах и чем это полезно
constexpr virtual foo()
Reflection
Куда можно будет засунуть восклицательный знак и чем это может быть полезно
тотальное нашествие constexpr в стандартную библиотеку

Самым ужасающим будет (скорее всего в c++20 не войдет, позже) Reflection. По сравнению с ним — текущие "шаблоны" — просто детский лепет. Так что, "большинству практикующих C++" придется либо переключить негатив c "шаблонов" на более ужасные вещи, либо, если они уж и впрямь сильно практикуют — расширить, включив туда, кроме "шаблонов" — еще и эти новые страшилки
Re: Templates
От: rg45 СССР  
Дата: 06.07.18 08:26
Оценка: +3
Здравствуйте, smeeld, Вы писали:

S>Заметил, что у большинства практикующих C++ достаточно негативное отношение к шаблонам в CPP.


Ну, на счет большинства — это ты погорячился, имхо.

S>Речь идёт не о использовании std или boost, которые состоят из таковых процентов на 80, а о написании кода с активным применением параметризации функций и типов. Это многими считается чуть ли не признаком недостатка квалификации, типа матёрый плюсовик всегда найдёт способ расписать без создания параметризованных типов, и вообще найдёт способ писать на C++ как можно проще. Это вообще что такое? Если принять это мнение за справедливое, то получается, что std и boost писали джуны несмышлённые и не знающие как просто писать на CPP?


Святая церковь тоже поначалу выступала против электричества: было большое количество травм и несчастных случаев. И вообще, без него вполне можно было обходиться — и воды натаскать, и скотину покормить. А электричество нужно было только тем, кто хотел повыпендриваться.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 07.07.2018 12:01 rg45 . Предыдущая версия . Еще …
Отредактировано 07.07.2018 12:00 rg45 . Предыдущая версия .
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.