Есть флаговый enum, для него определены все бинарные операции, возвращают тот же enum.
Я пока не делал operator bool, мало ли что вылезет. Но, в условных операторах уже устал писать ==0 / !=0.
Ну вот и подмывает уже эту мелочь переделать. Тут ещё анноит то, что с интегральными типами можно просто написать if (condition), а с enum'ом надо писать if (condition!=0)
Здравствуйте, Marty, Вы писали:
M>Есть флаговый enum, для него определены все бинарные операции, возвращают тот же enum.
M>Я пока не делал operator bool, мало ли что вылезет.
А как ты собираешься сделать оператор bool для перечисления? Его ведь можно сделать только как функцию-член.
M>Но, в условных операторах уже устал писать ==0 / !=0.
Если условный оператор понимает конструкции if(x==0) и if(!=0), значит enum обычный, unscoped, а значит, услоный оператор так же точно способен понять и конструкции if(x) и if(!x) и никаких операторов для этого определять не нужно.
M>На какие грабли можно нарваться?
Да грабли могут быть самые разноообразные. Вот из недавнего, например. Был у нас чудо-юдо-супер-говно класс, написанный хрен знает когда для якобы эффективной работы со всякими строками. Объекты этого класса часто использовались в качестве ключей ассоциативных контейнеров. Для этих целей в этом классе был определены операторы сравнения (обычные). И вот, настало время переходить на C++20. Ну, попыхтели-попыхтели и перешли. И, как потом выяснилось, все ассоциативные контейнеры в новой реализации стандартной библиотеке используют уже новый spaceship оператор <=>. Такого оператора в этом классе, конечно же, не было. Зато в этом классе были определены операторы неявного преобразования к char* и const char*, для которых (внезапно) оператор <=> определен. Ну вот эти операторы преобразования и подхватились. И пошло сравнение голых указателей, вместо сравнения содержимого строк. И ведь все успешно откомпилировалось, а ошибку ловили уже в рантайме. А, как известно, чем дурнее ошибка, тем дольше ты ее будешь ловить. И это лишь единичный пример, а вообще, это очень западлистая штука, эти неявные преобразования. И никакой фантазии не хватит, чтоб представить, во что это счастье может вылиться.
Здравствуйте, rg45, Вы писали:
M>>Я пока не делал operator bool, мало ли что вылезет.
R>А как ты собираешься сделать оператор bool для перечисления? Его ведь можно сделать только как функцию-член.
А вот это видимо то, почему я сразу так не сделал, и просто забыл
А есть какие-нибудь варианты?
M>>Но, в условных операторах уже устал писать ==0 / !=0.
R>Если условный оператор понимает конструкции if(x==0) и if(!=0), значит enum обычный, unscoped, а значит, услоный оператор так же точно способен понять и конструкции if(x) и if(!x) и никаких операторов для этого определять не нужно.
enum — scoped
#define MAKE_ENUM_FLAGS(TEnum) \
inline constexpr bool operator==(TEnum a, std::underlying_type<TEnum>::type b) \
{ \
using TUnder = typename std::underlying_type<TEnum>::type; \
return static_cast<TUnder>(a) == b; \
} \
inline constexpr bool operator==(std::underlying_type<TEnum>::type a, TEnum b) \
{ \
using TUnder = typename std::underlying_type<TEnum>::type; \
return a == static_cast<TUnder>(b); \
} \
inline constexpr bool operator!=(TEnum a, std::underlying_type<TEnum>::type b) \
{ \
using TUnder = typename std::underlying_type<TEnum>::type; \
return static_cast<TUnder>(a) != b; \
} \
inline constexpr bool operator!=(std::underlying_type<TEnum>::type a, TEnum b) \
{ \
using TUnder = typename std::underlying_type<TEnum>::type; \
return a != static_cast<TUnder>(b); \
} \
M>>На какие грабли можно нарваться?
R>Да грабли могут быть самые разноообразные. Вот из недавнего, например. Был у нас чудо-юдо-супер-говно класс, написанный хрен знает когда для якобы эффективной работы со всякими строками. Объекты этого класса часто использовались в качестве ключей ассоциативных контейнеров. Для этих целей в этом классе был определены операторы сравнения (обычные). И вот, настало время переходить на C++20. Ну, попыхтели-попыхтели и перешли. И, как потом выяснилось, все ассоциативные контейнеры в новой реализации стандартной библиотеке используют уже новый spaceship оператор <=>. Такого оператора в этом классе, конечно же, не было. Зато в этом классе были определены операторы неявного преобразования к char* и const char*, для которых (внезапно) оператор <=> определен. Ну вот эти операторы преобразования и подхватились. И пошло сравнение голых указателей, вместо сравнения содержимого строк. И ведь все успешно откомпилировалось, а ошибку ловили уже в рантайме. А, как известно, чем дурнее ошибка, тем дольше ты ее будешь ловить. И это лишь единичный пример, а вообще, это очень западлистая штука, эти неявные преобразования. И никакой фантазии не хватит, чтоб представить, во что это счастье может вылиться.
Здравствуйте, Marty, Вы писали:
M>На какие грабли можно нарваться?
грабли уже вроде описали. Лично я вообще не выношу оператор bool в стандартной библиотеке. Столько уже ошибок в рантайме отлавливал, когда optional неявно кастится к bool.
Но чтобы грабли наставить можно сделать enum через структуру
Здравствуйте, Marty, Вы писали:
M>уже устал писать
Годы (десятилетия) идут, а у плюсовиков всё те же проблемы
Вы реально все настолько гении, что высокоуровневый дизайн и архитектура никогда не вызывают вопросов, что там перформанс тесты писать не надо, сопровождаемость запредельная — код читается лучше, чем литературный русский язык? Почему половина вопросов в этом форуме это какое-то дрочилово на 5 лишних букв?
Здравствуйте, rosencrantz, Вы писали:
R>Годы (десятилетия) идут, а у плюсовиков всё те же проблемы
R>Вы реально все настолько гении, что высокоуровневый дизайн и архитектура никогда не вызывают вопросов, что там перформанс тесты писать не надо, сопровождаемость запредельная — код читается лучше, чем литературный русский язык? Почему половина вопросов в этом форуме это какое-то дрочилово на 5 лишних букв?
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, rosencrantz, Вы писали:
R>>Мне для общего развития — вот как раз чтобы не быть таким убогим
R>Так ты еще не достиг того уровня, чтоб что-то вякать на плюсовых форумах. "Приятные языки" со встроенными памперсами — вот пока твой уровень.
Ты что-то разошёлся с оценками C++ долгое время был моим основным языком — со школы, и первые нескольких лет работы. Я понимаю, что ты обижен и хочешь нахамить. Но вот ты уже 2 грубых сообщения написал — теперь может по делу что-то скажешь?
Здравствуйте, rosencrantz, Вы писали:
R>Ты что-то разошёлся с оценками C++ долгое время был моим основным языком — со школы, и первые нескольких лет работы.
Да я могу представить твой уровень. Это тебе кажется, что ты какой-то уникальный, а я тут таких как ты знаешь сколько повидал. Ну, например, какой тип результата у функции ниже:
template <typename T>
T foo(T&&);
?
R>Я понимаю, что ты обижен и хочешь нахамить. Но вот ты уже 2 грубых сообщения написал — теперь может по делу что-то скажешь?
Судя по твоему бодрому вступлению, ты сюда за этим и пришел, чтоб тебе нащелкали по носу и накрутили тебе твой поросячий хвост. Ну так ты получишь то, за чем пришел.
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, rosencrantz, Вы писали:
R>>Ты что-то разошёлся с оценками C++ долгое время был моим основным языком — со школы, и первые нескольких лет работы.
R>Да я могу представить твой уровень. Этот тебе кажется, что ты какой-то уникальный, а я тут таких как ты знаешь сколько повидал.
Ставишь диагноз по аватарке?
R>Ну, например, какой тип результата у функции ниже: R>
R>T foo(T&&);
R>
R>?
T& ? Я гадаю конечно. Не застал C++11, но не понимаю почему это важно. Мой вопрос ведь — про культуру C++. А она, как мне кажется, не изменилась со времён C++98.
R>Судя, по твоему бодрому вступлению, ты сюда за этим и пришел, чтоб тебе нащелкали по носу и накрутили тебе твой поросячий хвост. Ну так ты получишь то, за чем пришел.
Ты будешь отвечать на вопрос или нет? Если не будешь, мне твои метафоры и эпитеты не интересно читать.
Здравствуйте, rosencrantz, Вы писали:
R>T& ? Я гадаю конечно. Не застал C++11, но не понимаю почему это важно. Мой вопрос ведь — про культуру C++. А она, как мне кажется, не изменилась со времён C++98.
Я тебе об этом и говорю, что ты гадаешь. Ты пришел в область, в которой ни черта не смыслишь и делашь космические заявления, космической же глупости.
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, rosencrantz, Вы писали:
R>>T& ? Я гадаю конечно. Не застал C++11, но не понимаю почему это важно. Мой вопрос ведь — про культуру C++. А она, как мне кажется, не изменилась со времён C++98.
R>Я тебе об этом и говорю, что ты гадаешь. Ты пришел в область, в которой ни черта не смыслишь и делашь комические заявления, космической же глупости.
Знание некоторых базовых идей освобождает от знания многих конкретных фактов. Так чего, угадал или ты просто хочешь по-джентельменски слиться?
Здравствуйте, rosencrantz, Вы писали:
R>Знание некоторых базовых идей освобождает от знания многих конкретных фактов. Так чего, угадал или ты просто хочешь по-джентельменски слиться?
А кто тебе сказал, что ты знаешь базовые вещи? Ты сам так решил? У меня, например, другое впечатление сложилось.
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, rosencrantz, Вы писали:
R>>Знание некоторых базовых идей освобождает от знания многих конкретных фактов. Так чего, угадал или ты просто хочешь по-джентельменски слиться?
R>А кто тебе сказал, что ты знаешь базовые вещи? Ты сам так решил? У меня, например, другое впечатление сложилось.
Ты ещё помнишь вопрос, с которого началась эта ветка? Будет что-то по теме, или продолжишь выпендриваться своим знанием актуальных стандартов?
, я отлично помню. А кстати, ты на вопрос ветки не хочешь ответить?
R>Будет что-то по теме, или продолжишь выпендриваться своим знанием актуальных стандартов?
Во-первых, где я тут выпендривался знанием стандартов. А во-вторых, ты не охренел часом? Это кто из нас повыпендирваться сюда пришел?
Здравствуйте, rosencrantz, Вы писали:
R>Вы реально все настолько гении, что высокоуровневый дизайн и архитектура никогда не вызывают вопросов, что там перформанс тесты писать не надо, сопровождаемость запредельная — код читается лучше, чем литературный русский язык? Почему половина вопросов в этом форуме это какое-то дрочилово на 5 лишних букв?
Просто вам в ваших инкубаторах не всю правду рассказывают. Выращивают счастливое поколение, свободное от необходимости иметь мозги.
А ну-кась, архитектор ты наш, магистр "базовых вещей", а забацай-ка ты нам на каком-нибудь "приятном языке" аналог вот такой простенькой программки:
Здравствуйте, rg45, Вы писали: R>нам на каком-нибудь "приятном языке" аналог вот такой простенькой программки:
-- main.lua
function dot(a,b) local r=0
if #a~=#b then error "invalid args" end
for i=1,#a do r=r+a[i]*b[i] end
return r
end
function printf(...) print(string.format(...)) end
print[[/* main.c */
#include <stdio.h>
int main(int argc,char** argv) {]]
printf('\tprintf("%s\\n");',dot( {1,2,3}, {6,7,8} ) )
printf('\tprintf("%s\\n");',dot( {1,2,3,4,5}, {6.1,7.3,8.0,9,10} ) )
print[[ return 0;
}]]
require "utils"
function dot(a,b) local r=0
if #a~=#b then error "invalid args" end
for i=1,#a do r=r+a[i]*b[i] end
return r
end
T=template{
c1=dot( {1,2,3}, {6,7,8} ),
c2=dot( {1,2,3,4,5}, {6.1,7.3,8.0,9,10} ),
}
print(T[[
/* main.c */
#include <stdio.h>
int main(int argc,char** argv) {
printf("{{c1}}\n");
printf("{{c2}}\n");
return 0;
}
]])
utils.lua
function base64(s)
local n,a,res,b64
b64='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
n=0 a=0 s=s:gsub('[^A-Za-z0-9+/=]','');
local function ch(a,r,n) local x={}
a=a>>r for i=1,n do x[i]=(a>>8*(n-i))&255 end
return string.char(table.unpack(x))
end
local function tl() local r=''
if n==3 then r=ch(a,2,2)
elseif n==2 then r=ch(a,4,1) end
return r
end
res=s:gsub('[A-Za-z0-9+/=]',function(x) local r=''
if x=='=' then r=tl() n=4 else
a=a*64+b64:find(x)-1 n=n+1
if n==4 then r=ch(a,0,3) n=0 a=0 end
end
return r
end)
return res..tl()
end
function create(name,decoder) decoder=decoder or base64
local f=io.open(name,"wb")
return function(data) f:write(decoder(data)) f:close() end
end
function xml_encode(x)
local tab={ ['<']='<',['>']='>',
['&']='&',['"']='"',["'"]=''' }
return x:gsub("[<>&'\"]",function(v) return tab[v] end)
end
function template(G) G=G or _G local get_fn
function get_fn(m) local fn
fn=function(t) if t==nil then return fn end
if type(t)=='table' then G=setmetatable(t,{__index=G}) return fn end
if type(t)=='function' then
if m then return get_fn(function(x) return m(t(x)) end) end
return get_fn(t)
end
local r=t:gsub('{{([^}]+)}}',function(v)
local g=G for i in v:gmatch("[^%.]+") do
local p,fn=i:find('|')
if p then fn=i:sub(p+1) i=i:sub(1,p-1) end
if type(g[i])=='function' then g=g[i]() else g=g[i]
if g==nil then error("no variable "..i.." in {{"..v.."}}") end
end
if p then fn:gsub('[^|]+',function(f)
if G[f]==nil then error("no function "..fn.." in {{"..v.."}}") end
g=G[f](g)
end)
end
end
return g
end)
if m then r=m(r) end
return r
end
return fn
end
return get_fn()
end
function create_text(name,G) return create(name,template(G)) end
function ansi_encode(x)
local tab={ ['\0']='\\0',['\n']='\\n',['\r']='\\r',
['\t']='\\t',['\a']='\\a',['\\']='\\\\',['"']='\\"' };
return x:gsub('[\x00-\x1f\\\"\x80-\xFF]',function(v)
if tab[v]~=null then return tab[v] end
return string.format("\\x%02X",string.byte(v))
end)
end
function hex_encode(x)
return x:gsub('.',function(v)
return string.format("%02X",string.byte(v))
end)
end
function string.split(s,delim,limit,plain)
local res,pos,t,h={},1
delim=delim or ',' limit=limit or 0 plain=plain or false
while pos do
h,t=s:find(delim,pos,plain)
if h then h=h-1 t=t+1 end
limit=limit-1 if limit==0 then h=null t=null end
table.insert(res,s:sub(pos,h))
pos=t
end
return res
end
Здравствуйте, kov_serg, Вы писали:
_>Здравствуйте, rg45, Вы писали:
R>>нам на каком-нибудь "приятном языке" аналог вот такой простенькой программки:
_>