Как бы поизящнее прикрутить к enum ограничение области видимости в версиях до C++11?
Я пока не придумал ничего лучшего, чем заворачивать enum в одноименный namespace, но тогда на имя типа приходится ссылаться конструкцией вида EnumType::EnumType, что выглядит как-то коряво.
смотря чем ограничена эта область
кроме неймспейса еще можно структурой или классом оборачивать
и виден такой енум будет соответственно только в пределах класса или структуры
Здравствуйте, reversecode, Вы писали:
R>кроме неймспейса еще можно структурой или классом оборачивать R>и виден такой енум будет соответственно только в пределах класса или структуры
Это понятно. Тут основная проблема в том, чтобы определить константы с простыми, не уникальными именами вроде Day, Out или Upper. В scoped enum доступ к ним возможен только через квалификатор имени типа, и все выглядит очень изящно. Хочется сделать нечто похожее в C++03, но не слишком коряво.
для того их и улучшали в С++11 что бы поубирать эти ограничения
ну пусть будут
e_day, e_month e_upper
или
eDay, eMoth eUpper и никогда не было проблем
или
enum SomeStatusValue { ssValue1, ssValue2, ssValue3 };
поизучайте всякие code style
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Как бы поизящнее прикрутить к enum ограничение области видимости в версиях до C++11?
ЕМ>Я пока не придумал ничего лучшего, чем заворачивать enum в одноименный namespace, но тогда на имя типа приходится ссылаться конструкцией вида EnumType::EnumType, что выглядит как-то коряво.
А что именно коряво?
struct Bit { enum { B0=1, B1=2, B2=4, B3=8 }; };
//int x = Bit::B0 | Bit::B2;
Здравствуйте, kov_serg, Вы писали:
R>>>Bit x = Bit::B0 | Bit::B2;
ЕМ>>Именно.
_>Зачем?
Затем, чтоб компилятор отслеживал тип переменной, и обламывал ошибочные попытки присвоить ей произвольное числовое значение. Я б с удовольствием запретил и преобразование enum в int по умолчанию, оставив только явное, но компиляторы такого не умеют.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Затем, чтоб компилятор отслеживал тип переменной, и обламывал ошибочные попытки присвоить ей произвольное числовое значение. Я б с удовольствием запретил и преобразование enum в int по умолчанию, оставив только явное, но компиляторы такого не умеют.
Я использую примерно такой подход:
struct Color
{
enum t
{
Red,
Green,
Blue
};
};
При указании типа следует использовать Color::t, константы указываются как Color::Red, Color::Green и Color::Blue.
При попытке присвоить Color::t "что-нибудь" компилятор обычно ругается.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Здравствуйте, kov_serg, Вы писали:
R>>>>Bit x = Bit::B0 | Bit::B2;
ЕМ>>>Именно.
_>>Зачем?
ЕМ>Затем, чтоб компилятор отслеживал тип переменной, и обламывал ошибочные попытки присвоить ей произвольное числовое значение. Я б с удовольствием запретил и преобразование enum в int по умолчанию, оставив только явное, но компиляторы такого не умеют.
Вам не кажется что это доведение до абсурда?
Може вы еще и такие типы хотите PositiveDouble, RangeDouble, MultiRangeDouble, DoubleWithAcceptedValues
и еще такие DoubleMeter, FloatTime, LongDoubleMass ...
И потом трахаетесь с их преобразованиями?
Может лучше не плодить сущности, пораждаю лишнюю энтропию, а использовать по максимуму имеющиеся?
О, спасибо. Я такое тоже использую с namespace, когда имя типа можно естественным образом разделить на названия двух независимых сущностей, а вот когда разделить нельзя — не придумал ничего лучше, чем давать одинаковые имена и тому, и другому. Вроде бы очевидная и элементарная идея, а вот не пришла в голову.
Здравствуйте, kov_serg, Вы писали:
_>Вам не кажется что это доведение до абсурда?
Никоим образом. Если в языке есть идея строгой типизации — ее нужно использовать везде, кроме исключительных случаев.
_>Може вы еще и такие типы хотите PositiveDouble, RangeDouble, MultiRangeDouble, DoubleWithAcceptedValues _>и еще такие DoubleMeter, FloatTime, LongDoubleMass ...
Не хочу. По той простой причине, что тип double предназначен для вычислений, и диапазон его значений по определению не имеет разрывов, кроме пары неопределенностей. А тип enum, наоборот, для вычислений по определению не предназначен, и его значения не обязаны быть смежными. По сути, это такой примитивный аналог множества с постоянной мощностью 1, из которого можно принудительно сделать множества мощностью до 32-64.
_>Может лучше не плодить сущности, пораждаю лишнюю энтропию, а использовать по максимуму имеющиеся?
Имеющиеся сущности лучше использовать, когда они добавляют читабельности, безопасности и эффективности. Я бы хотел иметь в языке еще несколько возможностей для ограничения свободы компилятора по неявному преобразованию типов, а также пару десятков дополнительных предупреждений.
Изящные решения. Но в критичных по времени конструкциях нужно использовать с осторожностью — на элементарные с виду конструкции компилятор в отладочном режиме нагенерит много кода, да еще с вызовами, скоростью может резко упасть.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Не хочу. По той простой причине, что тип double предназначен для вычислений, и диапазон его значений по определению не имеет разрывов, кроме пары неопределенностей. А тип enum, наоборот, для вычислений по определению не предназначен, и его значения не обязаны быть смежными. По сути, это такой примитивный аналог множества с постоянной мощностью 1, из которого можно принудительно сделать множества мощностью до 32-64.
Вот например функция sqrt ждёт положительные значения, asin значение из диапазона [-1..1]. Так что вполне можно использовать типы с ограничениями. Более того иногда хочется проверки на переполнения например у целых чисел.
ЕМ>Имеющиеся сущности лучше использовать, когда они добавляют читабельности, безопасности и эффективности. Я бы хотел иметь в языке еще несколько возможностей для ограничения свободы компилятора по неявному преобразованию типов, а также пару десятков дополнительных предупреждений.
Всё же вы видимо хотите ограничивать не компилятор, а программистов которые будут работать с этим кодом.
Вам стоит использовать не C++, он явно преследует иные цели.