То есть void foo(Foo); foo(50) - это хороший код? :)
Вопрос не в хорошести. Вопрос в валидности. Насколько мне помнится, присваивать enum-у значение, которое в нём не определено - это UB.
Всё будет валидно, если поправить на Foo value = Foo{50} (см. std::byte)
Я так понял, что ты хочешь, чтобы это было бы НЕВАЛИДНО, нет?
Изначальный запрос был в том, чтобы оба типа вели себя как обычный тип, но нельзя было сконвертировать один в другой: 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&)
If the underlying type is not fixed and the source value is out of range, the result is unspecified (until C++17)undefined (since C++17). (The source value, as converted to the enumeration's underlying type if floating-point, is in range if it would fit in the smallest bit field large enough to hold all enumerators of the target enumeration.) Otherwise, the result is the same as the result of implicit conversion to the underlying type.
Ок, спасибо, буду иметь ввиду.
А ещё можно очень быстро налепить аналогичный класс. Ну, два в смысле. Или один шаблонный и инстанциировать. Ну и ты конечно понимаешь, что ты занимаешься полной ерундой, а именно: приписываешь существующим конструкциям языка несвойственные им возможности и назначение.
Что если я хочу вот такое: using Foo = std::string; using Bar = std::string; Foo foo = "hello"; Bar bar = foo; // Error: could not cast Foo to const Bar& in Bar::Bar(const Bar&)
Вот как раз выше дал тебе ответ...
Это не я :) Там выше по переписке уже привели пример библиотеки, которая решают эту задачу (плохо и некрасиво решает, но решает). В моей работе я не припомню, чтобы мне уж очень сильно нужен был strong typedef
Ты мультик про циплёнка смотрел, да ? "Кокое всё зелёное, коко..." и так далее. Что лиса говорила?
Очень хочется стронг тайпдефы, но не очень понятно чего конкретно хочется. Стронг тайпдефы позволяют не складывать абсолютные пути и не делить киловатты на часы. При этом, когда начинаешь разбирать детали - сразу непонятно, скажем, можно ли сложить абсолютные пути как строки, если очень хочется
Нужно дать возможность в любой момент откатиться к основному типу.
В каком смысле откатиться, например, в таком можно? std::string foo(abs_path const& a, abs_path const& b) { return static_cast<std::string const&>(a) + static_cast<std::string const&>(b); }
Да в любом - хоть функцию библиотечную std::to_underlying как у енумов
А в таком? std::string foo(abs_path const& a, abs_path const& b) { return static_cast<std::string const&>(a) + b; }
Это уже зависит от того как мы сделаем наследование операторов. Я пока не могу сформулоировать как я бы хотел.
А в таком? Ковариантен или нет? struct i_some { virtual ~some() = default; virtual std::string foo() = 0; }; struct some : i_some { abs_path foo() override; }
Ковариантность вообще только для указателей вроде работает, так что вряд ли
Если ссылки можно кастовать, почему он не ковариантен?
Я знал, что ты придёшь и покажешь много замечательных примеров :)
Ну такой код просто для наследования будет работать?
И да, еще в таком вот можно? abs_path foo(std::string const& a, std::string const& b) { return static_cast<abs_path const&>(a) + static_cast<abs_path const&>(b); }
Обсуждают сегодня