Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>>>Потому, что enum создает группу идентификаторов, объединенных общей идеей
BFE>>И для этого они лежат в namespace.
ЕМ>Тогда почему там не лежат члены классов?
Потому, что их объединение производится через class
ЕМ>>>Почему в обсуждаемом примере все идентификаторы начинаются на E?
BFE>>Предполагаю, что это сокращение от слова ERROR.
ЕМ>А зачем нужен такой префикс?
Чтобы показать, что всё это коды ошибок.
ЕМ>Уникальность обеспечивается и без него.
Ни с префиксом, ни без префикса уникальность не обеспечивается.
BFE>>Вот если их поместить в отдельный namespace, то они и не будут выбиваться из схемы (раз уж изначально это не было сделано)
ЕМ>Изначально, напомню, инкапсуляции не было и для полей структур. Ее тоже зря сделали? 
Наоборот, делали не зря. Зря не сделали этого с enum и зря перечислениям не запретили присваивать численные значения.
BFE>>использовать #define для констант уместнее, чем enum.
ЕМ>Я бы сказал, что уместнее использовать [static] const, а при невозможности — #define.
Но это для разрозненных констант, от которых не ожидается какой-либо регулярности. Если же константы хотя бы в основе завязаны на перечисление, то вполне логично определять их в перечислении.
Нет, не логично. Константы логично объединить в множество или положить в одно scope-пространство, но не в перечисление.
BFE>>Вот сейчас уже есть нормальные константы. Вы перестали использовать перечисления для того, чтобы задавать константы?
ЕМ>Я ж говорил, что для "просто констант" давно использую [static] const.
Почему не constexp ?
| | Скрытый текст |
| | #include <iostream>
#include <stdexcept>
constexpr int next(int n) { return 1 + n; }
constexpr int asdf = 1;
constexpr int asdg = next(asdf);
int main()
{
std::cout << '\n';
std::cout << "asdf = " << asdf;
std::cout << '\n';
std::cout << "asdg = " << asdg;
constexpr int arr[asdg] = {asdf, asdg};
int x = 2;
switch(x)
{
case arr[0]:
std::cout << '\n' << "arr[0] ";
break;
case arr[1]:
std::cout << '\n' << "arr[1]";
break;
}
}
|
| | |
ЕМ>Но, если мне нужны константы, например, для кодов ошибок, разделенных на группы (по степени серьезности, или по ситуациям, по связанным объектам и т.п.), то альтернативой enum будет только ручной инкремент. Вы предлагаете использовать его?
Можно и инкремент, если он вам зачем-то нужен, хотя я с трудом представляю ситуацию, где ТАКОЕ может понадобиться.
Я вообще не понимаю, зачем использовать
коды ошибок. У ошибки есть имя — этого достаточно. А код — он может меняться от системы к системе, ну, как в исходном примере, с EAGAIN и EWOULDBLOCK.
Именно поэтому я для ошибок часто использую перечисления и никогда константы. И перечисления я использую именно как перечисления, то есть набор имен и никак не значений.
ЕМ>Если Вы до сих пор пытаетесь провести аналогию с шаблонными трюками, то это ж несопоставимые вещи.
Для меня это то же самое — использование конструкции языка не по назначению.
ЕМ>enum — простая конструкция, ее смысл очевиден любому, кто хоть более-менее знаком с языком. Она не порождает отдаленных последствий.
Да ну? Любому? Да 90% вообще не понимают (включая авторов стандарта), что такое перечисление и вы, похоже, из их числа, раз путаете перечисление с набором констант.
И вообще, попробуйте поспрашивать коллег, что выведет следующий код:
#include <iostream>
enum AB
{
a = 1,
b = 0xF0000000
};
enum CD
{
cd_c = 1,
cd_d = 0xF00000000
};
int main()
{
if ( sizeof(a) == sizeof(cd_c) )
std::cout << "yes";
else
std::cout << "no";
}
ЕМ> Ну и то, что в языке таки появился enum class, уже говорит о том, что проблему осознали, и приняли меры для ее устранения.
Нет, не осознали. Даже наоборот: они ввели
std::byte.
ЕМ> А что появилось в языке для замены шаблонной магии?
auto
ЕМ> Даже if constexpr можно применить только к исполняемому коду. Это не метапрограммирование, а издевательство.
Метапрограммирование ещё только предлагают, но какое-то некрасивое.