Size: a a a

2021 March 24

AC

Alex Chernov in pro.cxx
Или обертка
источник

S

Sergey in pro.cxx
Alex Chernov
Просто обертки чего то да стоят
Пишут что ничего:

https://www.fluentcpp.com/2017/05/05/news-strong-types-are-free/

Я наши обёртки дизассемблировал в простых случаях - тоже от простых типов не отличалось.
источник

АК

Александр Караев... in pro.cxx
Sergey
Кто нибудь знает, ожидается ли в пост-С++20 стандартах сильная типизация в духе
using Foo = int;
using Bar = int;
Foo foo = 0;
Bar bar = foo; // Error: could not cast Foo to const Bar& in Bar::Bar(const Bar&)

?
Были предложения, обычно такое называется strong typedef. И все предложения рушатся вопросами:
0. Должна ли конвертация из int в Foo или Bar быть явной или неявной? А наоборот? А между ними?
1. Должен ли operator== работать "из коробки" для таких типов (в том числе комбинации int==Foo, Foo==Bar)?
2. Должен ли std::hash работать также, как для оригинального типа?
3. Должны ли поддерживаться арифметические операции для Foo, у которого "базовый" тип их поддерживает?
4. Если ответы на все вопросы выше - нет, то почему нельзя взять struct Foo { int value; }?

P.S. Вообще, ответы на все эти вопросы у каждого свои, а универсального решения придумать не смогли
источник

AC

Alex Chernov in pro.cxx
Надо бенчмарк написать
источник

AC

Alex Chernov in pro.cxx
+1 строчка в листе надо...
источник

AC

Alex Chernov in pro.cxx
Тут вопрос как взаимодействовать с уже написанным кодом
источник

AC

Alex Chernov in pro.cxx
Third party
источник

S

Sergey in pro.cxx
Александр Караев
Были предложения, обычно такое называется strong typedef. И все предложения рушатся вопросами:
0. Должна ли конвертация из int в Foo или Bar быть явной или неявной? А наоборот? А между ними?
1. Должен ли operator== работать "из коробки" для таких типов (в том числе комбинации int==Foo, Foo==Bar)?
2. Должен ли std::hash работать также, как для оригинального типа?
3. Должны ли поддерживаться арифметические операции для Foo, у которого "базовый" тип их поддерживает?
4. Если ответы на все вопросы выше - нет, то почему нельзя взять struct Foo { int value; }?

P.S. Вообще, ответы на все эти вопросы у каждого свои, а универсального решения придумать не смогли
Спасибо.

Мне кажется, на вопросы 1 и 3 ответ должен быть "да", иначе используйте обычный using/typedef.

А есть ли где нибудь лог обсуждения со всем списком подобных вопросов? Чтобы будущие предложения на них заранее ответили.
источник

S

Sergey in pro.cxx
Александр Караев
Были предложения, обычно такое называется strong typedef. И все предложения рушатся вопросами:
0. Должна ли конвертация из int в Foo или Bar быть явной или неявной? А наоборот? А между ними?
1. Должен ли operator== работать "из коробки" для таких типов (в том числе комбинации int==Foo, Foo==Bar)?
2. Должен ли std::hash работать также, как для оригинального типа?
3. Должны ли поддерживаться арифметические операции для Foo, у которого "базовый" тип их поддерживает?
4. Если ответы на все вопросы выше - нет, то почему нельзя взять struct Foo { int value; }?

P.S. Вообще, ответы на все эти вопросы у каждого свои, а универсального решения придумать не смогли
0 - все конвертации максимально явные, почти как в Аде.
источник

S

Sergey in pro.cxx
Иначе старый using или обёртки с нужным поведением.
источник

W

Wild_Wind in pro.cxx
Александр Караев
Были предложения, обычно такое называется strong typedef. И все предложения рушатся вопросами:
0. Должна ли конвертация из int в Foo или Bar быть явной или неявной? А наоборот? А между ними?
1. Должен ли operator== работать "из коробки" для таких типов (в том числе комбинации int==Foo, Foo==Bar)?
2. Должен ли std::hash работать также, как для оригинального типа?
3. Должны ли поддерживаться арифметические операции для Foo, у которого "базовый" тип их поддерживает?
4. Если ответы на все вопросы выше - нет, то почему нельзя взять struct Foo { int value; }?

P.S. Вообще, ответы на все эти вопросы у каждого свои, а универсального решения придумать не смогли
0. Явная.
1. Да. Сравнения допустимы. Но через тег опцианальны.
2. Нет, это разные типы. С разными констрейнтами.
3. Да.

Итого - Ada Language, SubType Idiom.
источник

W

Wild_Wind in pro.cxx
Sergey
0 - все конвертации максимально явные, почти как в Аде.
:)
источник

W

Wild_Wind in pro.cxx
Wild_Wind
0. Явная.
1. Да. Сравнения допустимы. Но через тег опцианальны.
2. Нет, это разные типы. С разными констрейнтами.
3. Да.

Итого - Ada Language, SubType Idiom.
Осталось только контракты навешать.
источник

АК

Александр Караев... in pro.cxx
Wild_Wind
0. Явная.
1. Да. Сравнения допустимы. Но через тег опцианальны.
2. Нет, это разные типы. С разными констрейнтами.
3. Да.

Итого - Ada Language, SubType Idiom.
0. Почему?
1. Почему?
2. Почему?
3. Точно? А если у меня using strong user_id = int, что такое user_id{1} + user_id{2}? Или user_id{5} * user_id{7}?

Все эти вопросы скорее риторические, на них не нужно отвечать (всё, что пришло мне в голову сходу, на самом деле можно приплести много чего ещё - операторы сравнения, поведение при наследовании, правила алиасинга, всякие там friend'ы и т.д...). Просто для каждой задачи, как выяснилось, нужно что-то своё. Есть классный пост на эту тему - https://foonathan.net/2016/10/strong-typedefs/

Конкретных свежих пропозалов в стандарт я не нашёл, увы.
источник

A

Alex in pro.cxx
А что здесь можно предложить? Поскольку нет универсально правильного или даже единственного наиболее часто нужного варианта, я не вижу ничего лучше объявления кастомного класса.
источник

A

Alex in pro.cxx
А если в проекте есть несколько различных типов с одинаковой семантикой, то можно класс сделать шаблонным и переиспользовать.
источник

АК

Александр Караев... in pro.cxx
Alex
А что здесь можно предложить? Поскольку нет универсально правильного или даже единственного наиболее часто нужного варианта, я не вижу ничего лучше объявления кастомного класса.
Видимо, к этому и пришли. Простая задача - struct myT { T value; }
Сложная задача - библиотека с миллиардом рычагов для настройки
источник

A

Alex in pro.cxx
это ж надо было так заморочиться
источник

W

Wild_Wind in pro.cxx
Александр Караев
0. Почему?
1. Почему?
2. Почему?
3. Точно? А если у меня using strong user_id = int, что такое user_id{1} + user_id{2}? Или user_id{5} * user_id{7}?

Все эти вопросы скорее риторические, на них не нужно отвечать (всё, что пришло мне в голову сходу, на самом деле можно приплести много чего ещё - операторы сравнения, поведение при наследовании, правила алиасинга, всякие там friend'ы и т.д...). Просто для каждой задачи, как выяснилось, нужно что-то своё. Есть классный пост на эту тему - https://foonathan.net/2016/10/strong-typedefs/

Конкретных свежих пропозалов в стандарт я не нашёл, увы.
0. Разве не ради этого всё и задумывалось? Чтоб нельзя было положить FirstName в SecondName?
1. Типы разные, неявное сравнение недопустимо, ты прав. Иначе отстрел ног на ровном месте.

2,3 - ХЗ, от ситуации зависти, я б напилил концептов с разынми policy.
источник

D

Danya in pro.cxx
Sergey
Кто нибудь знает, ожидается ли в пост-С++20 стандартах сильная типизация в духе
using Foo = int;
using Bar = int;
Foo foo = 0;
Bar bar = foo; // Error: could not cast Foo to const Bar& in Bar::Bar(const Bar&)

?
enum class Foo : int {};
enum class Bar : int {};
источник